Exit Full View
Up

/Games/HexBall.foocad

HexBall

I have some ball bearings going spare, and I thoght I would make them into a sphere for heavy juggling !

The tricky part of the design was finding a way to print it without steep overhangs.

Print 8 pieces. You may also print a "center" piece in TPU. The glue the eight pieces to the center only, and you get enough flexibility to insert the balls (hopefully!)

FooCAD Source Code
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
import static uk.co.nickthecoder.foocad.chamferedExtrude.v1.ChamferedExtrude.*

class HexBall : Model {
    
    @Custom
    val ballD = 20.5

    // The size of the "inner" sphere.
    // A larger number will capture the balls more completely,
    // If you get this number "just right", you may be able to pop the balls
    // in and out of a TPU printed object. ???
    @Custom
    var innerScale = 1.25

    // I like to print a 2 to test the fit.
    // Adjust ballD and innerScale if the fit isn't quite perfect.
    // Only then will I print the remaining 6 pieces.
    @Custom
    var quantity = 8

    fun whole() : Shape3d {
    
        val hole = Sphere(ballD/2)
        val end = hole.tileX(2).tileY(2).center()
        val dist = ballD * Math.sqrt(2)
        val middle = hole.repeatX( 2, dist ).repeatY( 2, dist ).center().rotateZ(45)

        val holes = middle + end.translateZ( dist/2 ).mirrorZ().also()
        val sphere = Sphere( ballD * innerScale )

        val result = (sphere - holes)
        
        return result
    }

    @Piece
    fun eighth() = eighth(1)

    fun eighth( quantity : double ) : Shape3d {
        val sphere = Sphere( ballD * innerScale )
        val quarter = Cube( ballD *2 ).rotateZ(45)
        val hole = Sphere(ballD/2)
    
        val dist = ballD * Degrees.cos(60) //Math.sqrt(2)
        val piece = (sphere / quarter) -
            hole.translateY( ballD ) -
            hole.translateY( ballD ).rotateX(45).rotateZ(45).mirrorX().also()

        // 8 pieces will make a complete sphere.
        // But now lets make them easy to print, with less overhang, putting the
        // corner stright down, and then slicing it off for good bed contact.
        // NOTE. 54.735 isn't the "right" rotation, but my maths is poor :-(
        // I obtained this by trial and error (with a binary chop to get ever closer).
        val eighth = piece.rotateX(54.735).translateZ(-ballD*0.3) / Cube( ballD*2 ).centerXY()

        // See how the eighth piece compares to the whole sphere
        //return eighth + whole().rotateX(54.735).translateZ(-ballD*0.3).previewOnly()

        return if ( quantity %2 == 0) {
            eighth.tileX(quantity/2).tileY(2)
        } else {
            eighth.tileX(quantity)
        }
    }

    @Piece
    fun center() : Shape3d {

        val delta = ballD*0.3
        val debug = eighth(1).previewOnly()
            .rotateX(180)

        val size = ballD*0.52 + 0.3
        val solid = PolygonBuilder().apply {
            moveTo(0,-size)
            lineTo(size,0)
            lineTo(0,size)
        }.build().revolve().sides(4)
            .rotateZ(45)
            .rotateX(54.735)
            .toPolyhedron()
            .toOriginZ()

        return solid + debug
            
    }

    override fun build() : Shape3d {
        return center().translateY(-30) + eighth(quantity)
    }

}