Code Sketch


Sample Mandala
By: Lalit Pant
Category: Art
// needs Kojo v2.9.03
cleari()
setBackground(cm.rgb(10, 10, 10))

def centralFlower(stroke: Color, fill: Color) = Picture {
    right(90)
    setPenColor(stroke)
    setFillColor(fill)
    left(45)
    right(90, 100)
    right(90)
    right(90, 100)
}

def lotusPetal(stroke: Color, fill: Color, rad: Double, radExtent: Double,
               theta: Double, thetaExtent: Double) =
    penColor(stroke) * fillColor(fill) -> Picture.fromVertexShape { p =>
        val tDelta = thetaExtent / 2
        p.beginShape()
        p.curveVertexRt(rad, theta - tDelta)
        p.curveVertexRt(rad, theta - tDelta)

        val rExtent = radExtent / rad

        p.curveVertexRt(mathx.lerp(rad, rad * rExtent, 0.6), theta - tDelta * 22 / 30)
        p.curveVertexRt(mathx.lerp(rad, rad * rExtent, 0.7), theta - tDelta * 2 / 30)
        p.curveVertexRt(rad * rExtent, theta)
        p.curveVertexRt(mathx.lerp(rad, rad * rExtent, 0.7), theta + tDelta * 2 / 30)
        p.curveVertexRt(mathx.lerp(rad, rad * rExtent, 0.6), theta + tDelta * 22 / 30)

        p.curveVertexRt(rad, theta + tDelta)
        p.curveVertexRt(rad, theta + tDelta)
        p.endShape()
    }

def diya(stroke: Color, fill: Color, rad: Double, radExtent: Double,
         theta: Double, thetaExtent: Double) =
    penColor(stroke) * fillColor(fill) -> Picture.fromVertexShape { p =>
        val tDelta = thetaExtent / 2
        val rExtent = radExtent / rad
        p.beginShape()
        p.curveVertexRt(rad, theta)
        p.curveVertexRt(rad, theta)
        p.curveVertexRt(mathx.lerp(rad, rad * rExtent, 0.5), theta - tDelta / 4)
        p.curveVertexRt(rad * rExtent, theta)
        p.curveVertexRt(rad * rExtent, theta)
        p.endShape()

        p.beginShape()
        p.curveVertexRt(rad * rExtent, theta)
        p.curveVertexRt(rad * rExtent, theta)
        p.curveVertexRt(mathx.lerp(rad, rad * rExtent, 0.5), theta + tDelta / 4)
        p.curveVertexRt(rad, theta)
        p.curveVertexRt(rad, theta)
        p.endShape()
    }

def inscribedTriangle(vertexR: Double, vertexTheta: Double) = Picture.fromVertexShape { s =>
    import s._
    beginShape()
    vertexRt(vertexR, vertexTheta)
    vertexRt(vertexR, vertexTheta + 120)
    vertexRt(vertexR, vertexTheta + 240)
    vertexRt(vertexR, vertexTheta)
    endShape()
}

def inscribedSquare(vertexR: Double, vertexTheta: Double) = Picture.fromVertexShape { s =>
    import s._
    beginShape()
    vertexRt(vertexR, vertexTheta)
    vertexRt(vertexR, vertexTheta + 90)
    vertexRt(vertexR, vertexTheta + 180)
    vertexRt(vertexR, vertexTheta + 270)
    vertexRt(vertexR, vertexTheta)
    endShape()
}

def altar(r: Double, gateRFraction: Double, direction: Double) = Picture {
    setHeading(direction)
    hop(r)
    left(90)
    val glen = r * gateRFraction
    hop(glen)
    repeat(4) {
        forward(r - glen)
        left()
        forward(r - glen)
        right()
        forward(r / 10)
        right()
        forward(r / 4)
        left()
        forward(r / 10)
        left()
        forward(r / 4)
        forward(glen * 2)
        forward(r / 4)
        left()
        forward(r / 10)
        left()
        forward(r / 4)
        right()
        forward(r / 10)
        right(90)
    }
}

val pics = ArrayBuffer.empty[Picture]

pics.append(penColor(white) * fillColor(black.fadeOut(0.8)) -> inscribedTriangle(80, 90))
pics.append(penColor(white) * fillColor(black.fadeOut(0.8)) -> inscribedTriangle(80, -90))

repeatFor(0 to 11) { n =>
    val pic1 = rot(n * 30) -> centralFlower(white, cm.lightBlue)
    pics.append(pic1)
}

pics.append(penColor(white) * fillColor(black) -> Picture.circle(145))

repeatFor(0 to 5) { n =>
    val pic2 = lotusPetal(white, ColorMaker.hsl(0, 0.86, 0.66), 145, 180, n * 60, 60)
    pics.append(pic2)
}

pics.append(penColor(white) -> Picture.circle(190))

repeatFor(0 to 11) { n =>
    val pic2 = diya(white, ColorMaker.hsl(27, 0.86, 0.66), 200, 250, n * 30, 30)
    pics.append(pic2)
}

pics.append(penColor(white) * penWidth(10) -> Picture.circle(260))

repeatFor(0 to 11) { n =>
    val pic2 = lotusPetal(white, ColorMaker.hsl(0, 0.86, 0.66), 270, 290, n * 30, 30)
    pics.append(pic2)
}

pics.append(penColor(white) * penWidth(5) -> Picture.circle(300))

repeatFor(0 to 23) { n =>
    val pic2 = diya(white, ColorMaker.hsl(27, 0.86, 0.66), 305, 360, n * 15 + 7.5, 15)
    pics.append(pic2)
}

pics.append(penColor(white) * penWidth(5) -> altar(370, 0.2, 0))

//draw(pics)
draw(pics.reverse)
zoom(0.7)