Exit Full View
Up

/Games/NinePieceJigsaw.foocad

NinePieceJigsaw
FooCAD Source Code
import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*

class NinePieceJigsaw : Model {
    
    var pieceSize = 30
    var cornerRadius = 6
    var thickness = 3.0
    var tallSize = Vector2( 17, 5 )
    var shortSize = Vector2( 7, 16 )
    var bobbleRadius = 2.0
    var slack = 0.5
    var baseThickness = 0.6
    var wallSize = Vector2(6,3)

    // Pieces are chamfered. The bottom chamfer is larger to account for elephant foot on the first layer.
    var chamfer1 = 0.9
    var chamfer2 = 0.6

    fun piece() = Square( pieceSize -slack ).center().roundAllCorners( cornerRadius )

    fun extrude( piece : Shape2d ) = piece.chamferedExtrude( thickness, chamfer1, chamfer2 )

    fun tallBobble() = Square( tallSize ).roundAllCorners( bobbleRadius )
        .center().centerXTo( pieceSize/2 )

    fun tallHole() = tallBobble().offset( slack )

    fun shortBobble() = Square( shortSize ).roundAllCorners( bobbleRadius )
        .center().centerXTo( pieceSize/2 )

    fun shortHole() = shortBobble().offset( slack )

    @Piece
    fun red() = extrude(
        piece() + tallBobble() + tallBobble().rotate(-90)
    ).color("Red").darker()

    @Piece
    fun blue() = extrude(
        piece() + shortBobble() - shortHole().rotate(-90) - tallHole().rotate(180)
    ).color("DarkBlue")

    @Piece
    fun lightBlue() = extrude(
        piece() + shortBobble().rotate(90) - shortHole().rotate(-90) - shortHole().rotate(180)
    ).color("lightBlue")
    

    @Piece
    fun white() = extrude(
        piece() - shortHole().rotate(180) + tallBobble().rotate(90)
    ).color("White")

    @Piece
    fun blues() = blue().tileX(4,2)

    @Piece
    fun whites() = white().tileX(2,2)

    @Piece
    fun lightBlues() = lightBlue().tileX(2,2)

    @Piece
    fun base() : Shape3d {
        val inside = Square( pieceSize * 3 ).center().roundAllCorners(cornerRadius+slack)
        val outside = inside.offset( wallSize.x )

        return outside.extrude( baseThickness )
            .color("DimGrey")
    }

    @Piece
    fun wall() : Shape3d {
        val inside = Square( pieceSize * 3 ).center().roundAllCorners(cornerRadius+slack)
        val outside = inside.offset( wallSize.x )

        return (outside - inside).chamferedExtrude( baseThickness + wallSize.y, chamfer1, chamfer2 )
            .color("Red").darker()
    }

    @Piece
    fun tray() : Shape3d {
        val inside = Square( pieceSize * 3 ).center().roundAllCorners(cornerRadius+slack)
        val outside = inside.offset( wallSize.x )


        return (outside - inside).chamferedExtrude( baseThickness + wallSize.y, chamfer1, chamfer2 )
            .color("Red").darker() +

        outside.offset(-chamfer1).extrude( baseThickness )
            .color("DimGrey")
    }

    fun at( piece : Shape3d, x : int, y : int ) =
            piece.translate( x * pieceSize, y * pieceSize, 0 )

    override fun build() : Shape3d {
        return tray().topTo(thickness) + 
            at(red(), -1, 1 ) +
            at(blue(),  0, 1 ) +
            at(lightBlue(),  1, 1 ) +

            at(blue().rotateZ(-90).mirrorX(), -1,  0 ) +
            at(lightBlue().rotateZ(90),  0,  0 ) +
            at(blue().rotateZ(90),  1,  0 ) +

            at(white().rotateZ(-90), -1, -1 ) +
            at(blue(),  0, -1 ) +
            at(white(), 1, -1 )

    }

    @Piece
    fun cheat() : Shape3d {
       return tray().topTo(thickness) + 
            at(white().rotateZ(-90).mirrorY(), -1, 1 ) +
            at(blue(),  0, 1 ) +
            at(blue().rotateZ(-90),  1, 1 ) +

            at(blue().rotateZ(90), -1,  0 ) +
            at(red().rotateZ(45),  0,  0 ) +
            at(lightBlue().mirrorY(),  1,  0 ) +

            at(white().mirrorX(), -1, -1 ) +
            at(lightBlue().rotateZ(90).mirrorY(),  0, -1 ) +
            at(blue().rotateZ(180),  1, -1 )


    }

}