Exit Full View
ZipUp

/Games/Wooden Block Puzzle/CubeSnake.foocad

CubeSnake
FooCAD Source Code
import uk.co.nickthecoder.foocad.extras.v1.*
import static uk.co.nickthecoder.foocad.extras.v1.Extras.*
import uk.co.nickthecoder.foocad.threaded.v2.*
import uk.co.nickthecoder.foocad.smartextrusion.v1.*
import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.*

class CubeSnake : Model {

    var size = 20

    var chamfer = 1

    var holeDiameter = 4

    var clearance = 0.3

    var bumpSize = 1.0

    meth thread() : Thread = Thread( size/2 )

    meth plainCube() : Shape3d {
        return Square( size ).center().roundAllCorners( chamfer, 1 )
            .smartExtrude( size )
            .edges( Chamfer(chamfer) )
    }

    @Piece
    meth straight() : Shape3d {
        val plain = plainCube()
        
        val bumps = bumps().rotateX(90).translateZ(size/2)
        val divots = divots().rotateZ(90)

        return plain + bumps - straightHole() - divots
    }

    meth straightHole() : Shape3d {
        return Circle( holeDiameter/2 ).safeOverhang()
            .extrude(size + 2)
            .rotateX(90)
            .center()
            .translateZ( size/2 )

    }

    @Piece
    meth corner() : Shape3d {
        val plain = plainCube()
        val holeShape = Circle( holeDiameter/2 )//.safeOverhang().mirrorY()
        val path = PolygonBuilder().apply {
            moveTo( 0,-1 )
            lineBy( 0,1 )
            circularArcTo( Vector2(size/2,size/2), size/2, false, false )
            lineBy( 1,0 )
        }.buildPath()
        val hole = holeShape.extrude(path)
            .rotateX(-90)
            .translateZ(size)

        val bumps = bumps().translateZ(size/2)
        val divots = divots()
        return plain + bumps - hole - divots
    }

    meth bumps() : Shape3d {
        val one = Sphere( 1.5 ).translate(size*0.25, size*0.25, 0 )
            .topTo( size/2 + bumpSize )
        return one.mirrorX().also().mirrorY().also()

    }

    meth divots() : Shape3d {
        val one = Sphere( 1.5 + clearance ).translate(size*0.25, size*0.25, 0 )
            .bottomTo( size/2 - bumpSize - clearance )
        return one.mirrorX().also().mirrorY().also()
            .rotateY(90).translate(0, 0,size/2)
    }

    meth end() : Shape3d {
        val plain = plainCube()
        val hole = straightHole()
        val hollow = Square( size - 4 ).extrude( size - 4 ).center().bottomTo(2)
        val slice = Cube( size *2 ).centerX().rotateX(45).translateY(-size/2)
        val slot = Square( holeDiameter*0.6, size ).centerX().extrude(size).translateZ(size/2)

        val connection = Trapezium( size -2, 2 ).angle(-30).centerX().mirrorY()
            .extrude(size-4)
            .backTo(hollow.back).bottomTo(2)


        return plain - connection - slice - hollow - hole  - slot
    }

    @Piece
    meth endCover() : Shape3d {
        val plain = plainCube()
    
        val hole = straightHole()
        val hollow = Square( size - 4 - clearance*2 ).extrude( size - 4 ).center().bottomTo(2)
        val slice = Cube( size*2 ).centerX().rotateX(45).translateY(size/2-clearance)

        val connection = Trapezium( size -2 - clearance*2, 2 ).angle(-30).centerX().mirrorY()
            .roundCorner(3,0.3,1)
            .roundCorner(2,0.3,1)
            .extrude(size-2-clearance)
            .backTo( hollow.back)
        val connectionSupport = Square( hollow.size.x, hollow.size.y )
            .leftTo( hollow.left ).frontTo( hollow.front )
            .extrude( connection.size.z )
        val slot = Square( hollow.size.x - 2, size ).centerX().extrude(size)
            .translateZ(2)
            .frontTo(hollow.front)

        return plain - slice + connection + connectionSupport - slot 
    }

    @Piece
    meth endA() : Shape3d {
        return end() - divots().rotateZ(90)
    }

    @Piece
    meth endB() : Shape3d {
        val bumps = bumps().rotateX(-90).translateZ(size/2)
        val halfBumps = bumps - Cube( size, size - bumps.size.y, size ).centerXY()
        return end() + halfBumps
    }


    override fun build() : Shape3d {

        val endA = endA()
        val corner = corner().rotateX(90).bottomTo(0).translateY( size*2 )
        val straight = straight().rotateZ(-90).translate(size*1.5,size*1.5,0)
        val endB = endB().rotateZ(90).translate(size*3, size*1.5,0)

        val covers = endCover().translateX( size*1.5 ).translateX( size*1.5 ).also()

        return endA + corner + straight + endB + covers
    }

}