Code Sketch
Tricolour With Generative Art
Category: Art
cleari
val faces = 5
val radius = 150
val points = 50
setBackground(cm.darkSlateGray)
val theta = List.iterate(0.0, points)(_ + (2 * Math.PI / points))
val radiusValues = theta.map { thetaValue =>
Math.cos(Math.PI / faces) / Math.cos((thetaValue % (2 * Math.PI / faces)) - Math.PI / faces)
}
val distances =
radiusValues.sliding(2, 1).map { values =>
Math.abs(values(1) - values(0))
}.toList
val cummulativeDistances = distances.scan(0.0)(_ + _).map(_.toDouble).toList
val coordinates = (radiusValues.map(_ * radius), theta, cummulativeDistances).zipped.toList
def square = Picture.rect(60, 60)
.thatsFilledWith(red)
.thatsStrokeColored(black)
.thatsTranslated(-30, -30)
def angleRange(angle: Double): (Boolean, Boolean, Boolean, Boolean, Boolean) =
(
((45 * 0) until (45 * 1) - 5).contains(angle.toDegrees.toInt),
((45 * 1) - 5 until (45 * 3) + 30).contains(angle.toDegrees.toInt),
((45 * 3) + 30 until (45 * 5) - 10).contains(angle.toDegrees.toInt),
((45 * 5) - 10 until (45 * 7) + 30).contains(angle.toDegrees.toInt),
((45 * 7) until (45 * 9)).contains(angle.toDegrees.toInt),
)
def squareAtShapePoint(t: Double)(state: (Double, Double, Double)) = {
val (r, angle, d) = state
val color: Color = angleRange(angle) match {
case (true, _, _, _, _) => white
case (_, true, _, _, _) => cm.orange
case (_, _, true, _, _) => white
case (_, _, _, true, _) => green
case (_, _, _, _, true) => white
}
val (x, y) = (r * Math.cos(angle), r * Math.sin(angle))
square
.thatsRotated(-(d.toDegrees + t)).thatsTranslated(x, y)
.thatsFilledWith(color)
}
def toCoordinate(data: (Double, Double, Double)): (Double, Double) = {
val (r, angle, d) = data
(r * Math.cos(angle), r * Math.sin(angle))
}
def pentagonAtCenter = Picture.fromPath { p =>
val (startX, startY) = toCoordinate(coordinates.head)
p.moveTo(startX, startY)
coordinates.tail.map(toCoordinate).foreach {
case (x, y) => p.lineTo(x, y)
}
p.closePath()
}
def firstHalf(t: Double) =
coordinates.take(25).map(squareAtShapePoint(t) _)
def secondHalf(t: Double) =
coordinates.drop(25).map(squareAtShapePoint(t) _)
def fromLeft(t: Double) = picStack(
picStack(secondHalf(t)),
picStack(firstHalf(t)),
)
def fromRight(t: Double) = picStack(
picStack(firstHalf(t)),
picStack(secondHalf(t)),
)
val cb = canvasBounds
animateWithState(0.0) { s =>
erasePictures()
val shapeToShowOnlyRightPart = new java.awt.Rectangle(0, cb.getMinY.toInt, cb.width.toInt / 2, cb.getHeight.toInt)
val shapeToShowOnlyLeftPart = new java.awt.Rectangle(cb.getMinX.toInt, cb.getMinY.toInt, cb.width.toInt / 2, cb.getHeight.toInt)
val properPatternOnRight =
fromLeft(s).withClipping(shapeToShowOnlyRightPart).withPenColor(noColor)
val properPatternOnLeft =
fromRight(s).withClipping(shapeToShowOnlyLeftPart).withPenColor(noColor)
picStack(
pentagonAtCenter
.thatsFilledWith(white)
.withPenColor(noColor),
properPatternOnRight,
properPatternOnLeft,
chakra.thatsRotated(-s*0.3)
).draw
s + 2
}
def chakraLine =
trans(0, 4) *
fillColor(blue) *
penColor(blue) *
penThickness(0.5) ->
Picture.fromPath { s =>
s.moveTo(0, 0)
s.lineTo(-1, 20)
s.lineTo(0, 50)
s.lineTo(1, 20)
s.closePath()
}
def chakraOuterCircle =
penThickness(4) *
penColor(blue) ->
Picture.circle(54)
def chakraInnerCircle =
penThickness(0.5) *
fillColor(blue) *
penColor(blue) ->
Picture.circle(4)
def chakraLines = repeatRotatePicture(23, chakraLine, 15)
def chakra =
picStack(
chakraLines,
chakraOuterCircle,
chakraInnerCircle
)
def repeatRotatePicture(step: Int, picture: Picture, angle: Int): Picture =
if (step > 0) {
picStack(
picture,
rot(angle) -> repeatRotatePicture(step - 1, picture, angle)
)
}
else {
picture
}