Exit Full View
Up

/Games/WhistlingTop.foocad

WhistlingTop
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 MyModel : Model {
    
    var diameter = 40
    var height = 30
    var angledHeight = 10
    var shaftD = 5.0
    var shaftLength = 80

    var thickness = 2.0
    var slack = 0.3

    val openingH = 4
    val openingW = 10
    val openings = 3

    fun cavity( height : double ) : Shape3d {
        val circles = Circle( diameter/2-thickness ) - Circle( shaftD/2 + thickness )
        val opening = Cube( diameter*0.51, openingW, openingH )
            .translateZ((height-openingH)/2)
            .translateX(shaftD/2 + thickness)
            .centerY()

        return circles.extrude( height ) + opening.repeatAroundZ( openings )
    }

    @Piece
    fun top() : Shape3d {
        val flat = height - angledHeight
        val main = Circle( diameter/2 ).extrude( flat ) +
            Circle( diameter/2 ).extrudeToPoint( angledHeight ).translateZ(flat)

        val shaftHole = Cylinder.hole( flat + 1, shaftD/2, 12 ).translateZ(-1)
        return main - shaftHole - cavity( flat - thickness*2 ).translateZ(thickness)
    }

    @Piece
    fun shaft() : Shape3d {
        val radius = shaftD/2 - slack
        return ( Circle( radius ).sides( 30 ) -
            Square( shaftD ).centerX().mirrorY()
        ).extrude( shaftLength ).rotateX(90).centerY().tileX(2,0.3)
        
    }

    override fun build() : Shape3d {
        return top() / Cube( diameter * 2.2, 1, height * 2.2 ).center() +
            top().translateX(50)
    }
}