FooCAD Source Code/**
A wall mounted holder for 3 juggling balls. A companion to the ClubsHolder.
Print 1 "base" and three "ring" pieces. The rings can be TPU for a rubbery feel.
Glue with cyanoacrylate (AKA superglue).
*/
import static uk.co.nickthecoder.foocad.layout.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.Layout3d.*
import static uk.co.nickthecoder.foocad.screws.Screws.*
class BallHolder : Model {
// The diameter of the balls you wish to display.
@Custom
var ballD = 85
// The gap between adjascent balls
@Custom
var gap = 2
// The thickness of the rings (i.e. the "small" diameter of the torus).
@Custom
var ringT = 10
// The diameter of the rings compared to the ball's diameter.
@Custom
var ringScale = 0.6
fun ringD() = ballD * ringScale
@Piece
fun ring() : Shape3d {
val profile = Circle( ringT / 2 ).translateX( ringD()/2 ) /
Square( ringD() + 1 )
return profile.revolve().sides(50).color( "Green" )
}
@Piece
fun base() : Shape3d {
val rings = repeat(ring()).mirrorZ()
val line = ( Cylinder( ballD * 2 + gap * 2, ringT/2 ) / Cube( ballD*3 ).centerY() )
.centerY()
.rotateY(90)
.centerX()
.translateY(ringD()/2)
val coneH = (ballD + 4 - ringD()) / 2
val coneD = coneH*1.3
val keyHole = keyholeHanger( 4, 8 ).mirrorZ()
.rotateX(90)
.translateY( coneH )
.translateZ(-6)
val cone = (
(
Cylinder( coneH *0.8, ringT*0.6, coneD ) +
Cylinder( coneH * 0.2, coneD ).translateZ( coneH * 0.8)
) /
Cube( ringT*3 ).centerX()
).rotateX(-90) - keyHole
val cones = repeat( cone.translateY( ringD()/2 ) )
val result = line + rings + cones
return result.color("Yellow")
}
fun repeat( shape : Shape3d ) = shape.repeatX( 3, ballD + gap ).centerX()
@Piece
fun printBase() = base().mirrorZ().rotateZ(45) + Cube( 230, 230, 1 ).center().previewOnly()
override fun build() : Shape3d {
val balls = repeat( Sphere( ballD/2 ) )
.translateZ( ballD * 0.50 )
.previewOnly()
return base() + balls + repeat( ring() )
}
}