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 Sphericon : Model { // The "radius" of the solid. The distan @Custom var size = 30 @Custom var extend = 4 // Must be an even number >= 4 @Custom var sides = 6 @Custom var round = 5.0 @Custom var ringHeight = 20 // We need an "interferance" fit between the ring and the main part. // Adjust this, and re-print the ring until it is just right. // The better your printer, the smaller the slack ;-) // If it is too loose, damage the surfaces e.g. stab it with a knife, // without stabbing yourself! @Custom var slack = 0.2 // DO you want a circular ring, or a polygon? @Custom var circularRing = true @Piece fun main() : Shape3d { val rotation = if ((sides % 4) == 0) 0 else 180/sides var plain : Shape2d = Circle( size ).sides(sides).rotate(rotation) if ( extend <= 0 ) { plain = plain.roundAllCorners(round) } var profile = plain if ( extend > 0 && round > 0) { val extension = Circle( round ).translateX(size + extend) + Square( size + extend, round*2 ).centerY() profile = profile + extension.rotate(rotation).repeatAround( sides ) } val halfP = profile / Square( (size + extend)*3 ).centerY() val half = halfP.revolve(180).rotateX(90) val scale = if (sides == 4) 0.4 else 0.5 val groove = if (circularRing) { Circle( size*scale ).internalChamferedExtrude( ringHeight/2, 1, 0 ) } else { Circle( size*(scale-0.1) ).sides( sides ).internalChamferedExtrude( ringHeight/2, 1, 0 ) } return half - groove } // This used to be a ring, but I changed it to a solid. // Use a low infill (or even zero!) @Piece fun ring() : Shape3d { val scale = if (sides == 4) 0.4 else 0.5 val ring = if (circularRing) { Circle( size*scale - slack ).chamferedExtrude( ringHeight - 1, 0.5 ) //- } else { Circle( size*(scale-0.1) - slack ).sides(sides).chamferedExtrude( ringHeight - 2*slack, 0.5 ) // - } return ring.color("Green") } @Piece fun inspect() = (main() + ring().center() ) / ( Cube( 1, 100, 100 ).center() + Cube( 100, 1, 100 ).center() ) override fun build() : Shape3d { val main : Shape3d = main() val ring : Shape3d = ring() return main.tileY(2,2) + ring.translateY(-ring.size.y/2 - main.size.y/2- 2) } }