Pookkalam by Kevin Jacob

Code

# 100% code and joy :)
import math


def curves(
    x1, y1, x2, y2, steps, curv_angle, stroke="black", stroke_width=1, random=False
):  # a function that creates curves with lines and with desired number of steps and angle
    result = line(0, 0, 0, 0)
    curv_angle = math.radians(curv_angle)
    init_angle = math.atan((y2 - y1) / (x2 - x1))
    prev_x, prev_y = x1, y1
    if steps % 2 == 0:
        curv_angle_step = curv_angle / (steps / 2)
    else:
        curv_angle_step = curv_angle / ((steps - 1) / 2)
    curr_angle = curv_angle
    angle_sum = 0
    for i in range(steps):
        angle_sum += math.cos(curr_angle)
        curr_angle -= curv_angle_step
    if steps % 2 != 0:
        angle_sum += 1
    if not random:
        step = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / angle_sum
    else:
        step = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / steps
    curr_angle = init_angle + curv_angle
    for i in range(steps):
        curr_x, curr_y = (
            step * math.cos(curr_angle) + prev_x,
            step * math.sin(curr_angle) + prev_y,
        )
        result += line(
            prev_x, prev_y, curr_x, curr_y, stroke=stroke, stroke_width=stroke_width
        )
        prev_x = curr_x
        prev_y = curr_y
        curr_angle -= curv_angle_step
        if math.sqrt((curr_x - x1) ** 2 + (curr_y - y1) ** 2) >= math.sqrt(
            (x2 - x1) ** 2 + (y2 - y1) ** 2
        ):
            break
    return result


def birds(x, y, curvature, angle):  # creates birbs in the picture
    result = curves(x, y, x + 5, y + 5, 10, -curvature, stroke_width=2) + curves(
        x, y, x - 5, y + 5, 10, curvature, stroke_width=2
    ) | rotate(
        angle
    )  # scale(scale)
    return result


sun = circle(r=15, x=-27, y=34, fill="red", stroke="yellow", fill_opacity=0.8)
sun_lines = (
    line(20, 20, 21.414, 21.414, stroke="red")
    | rotate(90)
    | repeat(6, rotate(40))
    | scale(0.8)
    | translate(x=-27, y=34)
)
boat = (
    curves(20, 20, 64, -20, 10, -60, stroke_width=2)
    + curves(20, 20, 35, 0, 10, -20, stroke_width=2)
    + curves(30, -5, 35, 0, 10, -0, stroke_width=2)
    + curves(30, -5, 68, -5, 10, -30, stroke_width=2)
    + curves(60, -25, 68, -5, 10, -20, stroke_width=2)
)
boat = boat | repeat(50, translate(20 - 20 * 0.91, -20 + 20 * 0.97) | scale(0.95))
racers_back = circle(x=54, y=0, r=3, fill="grey") + ellipse(
    w=6, h=5, fill="black", x=54, y=-6
) + rectangle(w=6, h=3, x=54, y=-7, fill="black") | repeat(2, translate(x=10, y=2))
racers_front = (
    circle(x=43, y=5, r=3, fill="grey")
    + ellipse(w=6, h=15, fill="black", x=43, y=-5)
    + rectangle(w=6, h=10, x=43, y=-5, fill="black")
)
oars = (
    line(43, -5, 25, -35, stroke="#4f000b")
    | repeat(10, translate(x=0.2))
    | repeat(3, translate(x=11))
)
water_effect = curves(21, -33, 12, -34, 10, -50, "darkblue") | repeat(
    3, translate(x=11)
)
final_boat = boat + racers_back + racers_front + oars + water_effect | translate(
    y=-10, x=-5
)

sky_setting = sun + sun_lines + birds(15, 15, 50, 90) + birds(
    40, 30, 50, 90
) | translate(x=50)
tree_color = "#6c584c"
tree = (
    curves(-60, -30, -30, 20, 20, -30, stroke=tree_color, stroke_width=2)
    + curves(-50, -40, -25, 20, 20, -30, stroke=tree_color, stroke_width=2)
    + line(-25, 20, -30, 20, stroke=tree_color, stroke_width=2)
    + line(-60, -30, -50, -40, stroke=tree_color, stroke_width=2)
)
tree = tree | repeat(70, scale(0.97) | translate(x=-25 * 0.04, y=-20 * 0.03))


def leaf():
    palm_leafs_stalk = curves(0, 0, 38, -18, 10, 30, "brown")
    palm_leaf_front = line(0, 0, 0, 0)
    palm_leaf_temp = curves(-5, -10, 0, 0, 10, 30, "green")
    palm_leaf_back = line(0, 0, 0, 0)
    palm_leaf_temp2 = curves(0, 0, 2, 1, 10, 30, "green")
    for i in range(20):
        palm_leaf_front += palm_leaf_temp | translate(x=2.7, y=-0.1 * i) | scale(0.97)
        palm_leaf_temp = palm_leaf_temp | translate(x=2.7, y=-0.1 * i) | scale(0.97)
        palm_leaf_back += palm_leaf_temp2 | translate(x=2.7, y=-0.1 * i) | scale(0.99)
        palm_leaf_temp2 = palm_leaf_temp2 | translate(x=2.7, y=-0.1 * i) | scale(0.97)
    return (
        palm_leafs_stalk + palm_leaf_front + palm_leaf_back
        | rotate(-30)
        | repeat(7, rotate(20) | scale(0.9))
    )


palm_leaf = leaf() | scale(x=-1)
palm_leaf += leaf()
palm_leaf = palm_leaf | translate(x=-30, y=20) | scale(0.9)
coconut = (
    ellipse(w=6, h=9, fill="#5e503f")
    | repeat(3, rotate(-20) | translate(x=5, y=-2))
    | translate(x=-32, y=14)
)
tree = tree + coconut + palm_leaf
final_setting = sky_setting + final_boat + tree


bg_color = color(r=255, g=115, b=100, a=0.5)
background = circle(r=100, fill=bg_color, stroke_width=2)

r, g, x, y = 95, 105, 0, 0

for i in range(50):
    background += circle(r=r, fill=bg_color, stroke_width=0) | translate(x, y)
    bg_color = color(r=255, g=g, b=100, a=0.5)
    x += 3
    y += 3
    g += 20
    r -= 6
background += curves(-95, -20, -58, -20, 10, -40, stroke_width=3) | repeat(
    5, translate(x=37)
)
background += (
    curves(-40, -80, -30, -80, 3, -40, stroke_width=2)
    + curves(-35, -50, -25, -50, 3, -40, stroke_width=2)
    + curves(10, -55, 20, -55, 3, -40, stroke_width=2)
)
background = background | scale(0.68)
final_centre = background + final_setting

colors = (
    (
        "#2D2424",
        "#5C3D2E",
        "#B85C38",
        "orange",
        "yellow",
        "#F0EBCC",
        "#2C5F2D",
        "#97BC62FF",
        "#00539CFF",
        "#EEA47FFF",
        "#0063B2FF",
        "#9CC3D5FF",
        "#D198C5FF",
        "#E0C568FF",
        "#101820FF",
        "#FEE715FF",
        "#CBCE91FF",
        "#EA738DFF",
        "#B1624EFF",
    ),
    ("black", "brown", "orange", "yellow"),
    (
        "#CD113B",
        "#FF6464",
        "#FF8264",
        "#FFAA64",
        "#FFF5A5",
    ),
)
petal = line(0, 0, 0, 0)
x, y, i, k = 30, 70, 1, 0
while x >= 1 and y >= 0:
    if i % (30 - k * 3.5) == 0:
        k += 1
    petal += curves(0, 0, x, y, 5, 20, stroke_width=1, stroke=colors[0][k])
    x += 0.5
    y -= i * 0.017
    i += 1
outer_petal = line(0, 0, 0, 0)
x, y, i, k = 110, 80, 1, 0

while x >= 1 and y >= 0:
    if i % (29 - k * 7) == 0:
        k += 1
    outer_petal += curves(
        0, 0, x, y, 15, 80 - i * 0.7, stroke_width=1, stroke=colors[0][k]
    )
    x -= 0.5
    y -= i * 0.03
    i += 1
final_petal = petal | translate(y=57, x=-30) | repeat(6, rotate(60))
outer_petal = outer_petal | rotate(-70) | translate(y=115, x=-4) | repeat(6, rotate(60))
bg_circle = circle(r=150, fill="#FFDFAF", stroke_width=0, stroke="#DF711B")
size = 320
angle = 5
quad = line(0, 0, 0, 0)
for i, color in enumerate(colors[2]):
    quad += (
        rectangle(w=size, h=size, fill=color, stroke=color)
        | repeat(18, rotate(20))
        | rotate(angle)
    )
    size -= 20
    angle += 5

decor_color = "black"
decor = curves(-50, 30, -3, 0, 10, 40, stroke=decor_color) + curves(
    -50, 30, 0, 30, 10, 40, stroke=decor_color
)
decor += decor | scale(x=-1)
decor = (
    decor
    | repeat(100, scale(0.96) | translate(y=1))
    | rotate(0)
    | translate(y=150)
    | scale(0.8)
    | repeat(6, rotate(60))
)

outer_deco_color = "black"
outer_deco = ellipse(w=50, h=60, fill=outer_deco_color, stroke=outer_deco_color)
outer_deco += ellipse(
    w=40, h=60, x=-40, y=-0, fill=outer_deco_color, stroke=outer_deco_color
) + ellipse(
    w=40, h=50, x=-70, y=-0, fill=outer_deco_color, stroke=outer_deco_color
) + circle(
    r=23, fill="white", stroke="white", x=-55, y=15
) | rotate(
    30
)
outer_deco += ellipse(
    w=40, h=50, x=30, fill=outer_deco_color, stroke=outer_deco_color
) | rotate(-20)
outer_deco += circle(r=25, fill="white", stroke="white") | translate(x=15, y=13)
outer_deco += circle(
    r=20, stroke=outer_deco_color, fill=outer_deco_color, x=10, y=-40
) | repeat(2, translate(x=-35, y=-14))

inter_deco = line(0, 0, 0, 0)
side = 40
angle = 0
colors = [
    "#00A4CCFF",
    "yellow",
    "#F95700FF",
    "#00203FFF",
    "#ADEFD1FF",
    "#606060FF",
    "#D6ED17FF",
    "#ED2B33FF",
]  # ,"#D85A7FFF","#2C5F2D","#97BC62FF","#00539CFF","#EEA47FFF","#0063B2FF","#9CC3D5FF","#D198C5FF","#E0C568FF","#101820FF","#FEE715FF","#CBCE91FF","#EA738DFF","#B1624EFF",]
for i, color in enumerate(colors):
    inter_deco += (
        rectangle(h=side, w=side, fill=color, stroke=color, fill_opacity=0.5)
        | rotate(angle)
        | repeat(30, rotate(12))
    )
    side -= 5
    angle += 5
inter_deco = inter_deco | translate(x=25, y=30) | scale(0.7)
inter_deco += inter_deco | scale(0.8) | translate(x=-70, y=-30)
outer_deco += inter_deco
outer_deco = outer_deco | scale(0.8) | translate(0, 203) | repeat(10, rotate(36))

result = quad + bg_circle + outer_petal + final_petal + decor + final_centre | (
    scale(0.61)
)
outer_deco = outer_deco | scale(0.75)
outer_circle = circle(r=140, fill="black")
flower = (
    ellipse(w=8, h=30, fill="orange", stroke="orange")
    + circle(r=5, fill="red", stroke="yellow")
    | repeat(10, rotate(36))
    | scale(0.6)
    | translate(y=139, x=13)
    | repeat(18, rotate(20))
)
main_bg = rectangle(w=350, h=400, fill="white")
pookalam = main_bg + outer_circle + result + flower

show(pookalam)