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 FloatingSphere : Model { var pulleyA = 20 var pulleyB = 10 var bearingThickness = 8.0 // Must be larger than bearingThickness var pulleyThickness = 9.0 // The groovy will be pulleyThickness - pulleySide * 2 var pulleySide = 0.8 var innerR = 27 var thickness = 1.2 // Drill to a large size on one piece, and tap the other piece (using the // screw itself!) //var innerScrewD = 4 var slack = 0.3 var bearingD = 23 var rodD = 8.0 var lockSize = 4 var magnetD = 10.2 var magnetH = 1.1 @Piece fun pulley( radius : double ) : Shape3d { val inside = pulleyThickness - pulleySide * 2 val profile = PolygonBuilder().apply { moveTo(0, -pulleyThickness/2) lineTo(radius, -pulleyThickness/2) lineTo(radius, -inside/2) lineTo(radius-inside/2, -inside/2) // Assymetric lineTo(radius-inside/2, 0) lineTo(radius, inside/2) lineTo(radius, pulleyThickness/2) lineTo(0, pulleyThickness/2) }.build() return profile.revolve().sides(60) } @Piece fun doublePulley() : Shape3d { // Note, by adding a chamfer at the bottom of the hole for the bearing, // the bearing won't sit flush with the pulley, and therefore the inner // part of the bearing won't rub against the pulley. val bearingHole = Circle( bearingD/2 ).internalChamferedExtrude( bearingThickness, 1, -1 ) // Note the hole doesn't go all the way through, so that it can use bridging // Drill the thin piece of plastic with a drill. // The hole is larger than the rod. val rodHole = Cylinder.hole( pulleyThickness*6, rodD/2 + 0.5 ) .translateZ( pulleyThickness ) val result = pulley(pulleyA).toOriginZ() + pulley( pulleyB ).toOriginZ().translateZ(pulleyThickness - pulleySide) - bearingHole - rodHole return result.color("Silver") } @Piece fun inner() : Shape3d { val sides = 80 val slotA = Cylinder( pulleyThickness + slack*2, pulleyA + slack*2 ) .rotateX(90) .translateY(pulleyThickness-pulleySide/2+slack) .color("Red") val slotB = Cylinder( pulleyThickness - pulleySide + slack, pulleyB + slack*2 ) .rotateX(90) .translateY( -pulleySide/2 ) .color("Red") val rodGap = Cylinder.hole( innerR * 1.8, rodD/2 + slack ) .center() .rotateX(90) /* NO longer used val innerThickness = pulleyThickness + thickness*2 val cubes = Cube( innerR ) .translate( innerThickness, innerThickness, bandWidth/2) .mirrorX().also().mirrorY().also() val screws = Cylinder.hole( innerThickness*3, innerScrewD/2 ) .center() .translate( innerR*0.45, innerR*0.45, 0 ) .mirrorX().also().mirrorY().also() val lockVoid = ( Circle( innerR - lockSize ).sides(sides) - Circle( innerR - lockSize*2 ).sides(sides) - Square( innerR*2 , innerThickness*2 ).center() ) .extrude( lockSize ).translateZ( bandWidth/2 ) */ val hemi = Sphere( innerR ).sides(sides) / Cube( innerR * 2 ).centerXY() val hole = Cube( 2, 4, innerR*2.1 ).center() // Attemps to make the string for pulleyB easier. // However, both strings will cut into the plastic over time. val exit = Square( pulleyB + slack*2 ).rotate(45).center() .scale(1,pulleyA/pulleyB) .translate(0, (pulleyB+slack*2)/Math.sqrt(2)) .extrude( pulleyThickness ) .rotateX(90) val magnets = Cylinder.hole( magnetH+0.01, magnetD/2 ).translate( innerR/2, innerR/2, -0.01 ) .repeatAroundZ(4) return hemi - slotA - slotB - rodGap - exit - hole - magnets //- cubes - screws - lockVoid - holes } @Piece fun rod() : Shape3d { return ( Cylinder( innerR * 1.7, rodD/2 ).center().rotateY(90) .translateZ( rodD* 0.4 ) / Cube( innerR*2, rodD, rodD ).centerXY() ).toOriginZ() } @Piece fun inspect() = inner() + doublePulley().center().rotateX(90) override fun build() : Shape3d { return inner().translateY(innerR*2+2).also() + doublePulley().translateX(innerR*2) + rod().translate(innerR*2, innerR,0) } }