Code
#Code_a_Pookalam - Bichu Ben Kuruvilla
#defining all properties as dictionaries which are later passed to the member functions of pookalam object
#properties of the base square
base_square = {
"height":300,
"width":300,
"fill":"rgba(0,0,0,0.85)",
"stroke":"none"
}
#properties of the concentric sectors at the outer edge of the pookalam
outer_concentric_sectors = {
"concentric_count":5,
"sectors_count":12,
"max_radius":130,
"radius_gap":7,
"min_start_angle":8,
"min_end_angle":22,
"angle_gap":2,
"fill":["red","orange","gold","lemonchiffon","crimson"],
"stroke":"none"
}
#properties of the middle circle of the pookalam
middle_circle = {
"radius":95,
"fill":"crimson",
"stroke":"none"
}
#middle concentric sectors
middle_concentric_sectors = {
"concentric_count":6,
"stroke":["red","orange","lemonchiffon","orange","red","lemonchiffon"],
"initial_upper":95,
"initial_lower":90,
"rotate_angle":90,
"outer_sector_start":-37.5,
"outer_sector_end":52.5,
}
#properties to create a round of diamonds around the inner circle
circle_of_diamonds = {
"fill":["gold","orange","lemonchiffon"],
"stroke":["none","none","none"],
"width":[35,25,15],
"height":[70,60,50],
"repeat_per_round":[12,12,12],
"no_of_rounds":3,
}
#properties of the inner circle
inner_circle = {
"radius":22,
"fill":"crimson",
"stroke":"crimson"
}
#properties of the merged squares inside inner circle
merged_squares = {
"first_height":22,
"first_width":22,
"first_fill":"gold",
"first_stroke":"none",
"first_rotate_angle":45,
"second_points":[[0,0],[0,12],[-12,12],[-12,4],[-6,9]],
"second_fill":"orange",
"second_stroke":"none",
"second_no_of_repeat":4,
"second_rotate_angle":90
}
class pookalam:
#constructor
def __init__(self):
#all the shapes are appended to shape[] and are combined at the end
self.shape = []
#create the a square by passing properties as a dictionary
def square(self, dict):
square = rectangle(h = dict["height"], w= dict["width"], fill= dict["fill"], stroke= dict["stroke"])
self.shape.append(square)
#create a circle by passing properties as a dictionary
def circle(self, dict):
sole_circle = circle(r=dict["radius"], fill=dict["fill"], stroke=dict["stroke"])
self.shape.append(sole_circle)
#create the concentric sectors by passing properties as a dictionary
def outer_concentric_sectors(self, dict):
radius = dict["max_radius"]
sector_angular_width = 360/dict["sectors_count"]
#create circles starting from the outermost concentric one
for circle_number in range(dict["concentric_count"]):
sole_circle = circle(r=radius, fill=dict["fill"][circle_number], stroke=dict["stroke"])
self.shape.append(sole_circle)
#angles to determine limits to which lines must be drawn
start_angle = sector_angular_width + dict["min_start_angle"]
end_angle = sector_angular_width + dict["min_end_angle"]
#multiple lines are draw to the left and right of each sector to create a thick boundary
sole_line = line(x1=0, y1=0, x2=dict["max_radius"], y2=0, stroke=dict["fill"][circle_number], stroke_width=2)
lines = sole_line | rotate(start_angle) | repeat(dict["angle_gap"]*4, rotate(angle=0.25))
sole_sector = lines
sole_line = line(x1=0, y1=0, x2=dict["max_radius"], y2=0, stroke=dict["fill"][circle_number])
lines = sole_line | rotate(end_angle) | repeat(dict["angle_gap"]*4, rotate(angle=-0.25))
sole_sector = sole_sector + lines
#generate multiple sectors from one sector
sectors = sole_sector | repeat(dict["sectors_count"], rotate(angle=sector_angular_width))
self.shape.append(sectors)
#with each interior circle the width of the sector increases
dict["min_start_angle"] = dict["min_start_angle"] - dict["angle_gap"]
dict["min_end_angle"] = dict["min_end_angle"] + dict["angle_gap"]
radius = radius-dict["radius_gap"]
#function to create the equidistant concentric sectors in the middle section that together forms a concentric circle
def middle_concentric_sectors(self, dict):
#find angular width occupied by a group of adjacent sectors such that all colours in dict["stroke"] are used
sector_angular_width = dict["outer_sector_end"]-dict["outer_sector_start"]
y=90
#repeat for each layer of sector
for i in range(dict["concentric_count"]):
sole_sector = line(x1=0, y1=0, x2=0, y2=0)
#each group of sectors having all the required colors are created
for j in range(len(dict["stroke"])):
sole_line = line(x1=0, y1=dict["initial_lower"], x2=0, y2=dict["initial_upper"], stroke=dict["stroke"][j], stroke_width=3)
sole_line = sole_line | rotate(dict["outer_sector_start"]+ (j*sector_angular_width/6) )
sole_sector = sole_sector + (sole_line | repeat((sector_angular_width/6), rotate(angle=1)))
#each group is repeated to complete a circle
sectors = sole_sector | repeat(360/dict["rotate_angle"], rotate(angle=dict["rotate_angle"]))
self.shape.append(sectors)
#reducing y values for next layer of sectors
dict["initial_upper"] = dict["initial_upper"]-9
dict["initial_lower"] = dict["initial_lower"]-9
#function to create the diamond pattern
def circle_of_diamonds(self, dict):
#an iteration for each circlular round of diamonds
for i in range(dict["no_of_rounds"]):
#each diamond shape has 4 points
p1 = point(x=0, y=0)
p2 = point(x=-dict["width"][i]/2, y=2*dict["height"][i]/3)
p3 = point(x=0, y=dict["height"][i])
p4 = point(x=dict["width"][i]/2, y=2*dict["height"][i]/3)
diamond = polygon([p1,p2,p3,p4], fill=dict["fill"][i], stroke=dict["stroke"][i])
#a round of diamonds are created using a single diamond
diamonds = diamond | repeat(dict["repeat_per_round"][i], rotate(angle=360/dict["repeat_per_round"][i]))
self.shape.append(diamonds)
#function to create pattern that looks like merged squares inside inner circle
def merged_squares(self, dict):
p = []
#the first(bottom) square is created and rotated
first_square = rectangle(h= dict["first_height"], w= dict["first_width"], fill= dict["first_fill"], stroke= dict["first_stroke"])
first_square = first_square | rotate(dict["first_rotate_angle"])
self.shape.append(first_square)
#create a single part of the second square using some points
for i in dict["second_points"]:
p.append(point(x=i[0], y=i[1]))
partial_square = polygon(p, fill=dict["second_fill"], stroke=dict["second_stroke"])
#generate the second square from it's partial parts
second_square = partial_square | repeat(dict["second_no_of_repeat"], rotate(angle=dict["second_rotate_angle"]))
self.shape.append(second_square)
#display all the shapes present in shape[]
def display(self):
show(combine(self.shape))
#create pookalam object and call member functions
obj = pookalam()
obj.square(base_square)
obj.outer_concentric_sectors(outer_concentric_sectors)
obj.circle(middle_circle)
obj.middle_concentric_sectors(middle_concentric_sectors)
obj.circle_of_diamonds(circle_of_diamonds)
obj.circle(inner_circle)
obj.merged_squares(merged_squares)
obj.display()