sketch.py
# -*- coding: utf-8 -*-
import math
import random
from typing import List
import q5
from matplotlib import colors as mc
N = 200
palette = [
(245, 93, 116),
(69, 97, 244),
(245, 196, 44),
(56, 245, 94),
]
def set_saturation(color, s):
# s in [0.0, 1.0]
color_rgb = tuple(map(lambda x: x / 255, color))
color_hsv = mc.rgb_to_hsv(color_rgb)
color_hsv[1] = s
color_rgb_mod = mc.hsv_to_rgb(color_hsv)
return tuple(map(lambda x: int(x * 255), color_rgb_mod))
class Shape:
def __init__(self, a=64.0, b=300.0,
rot_speed=12.0, spike_freq=8.0, color=(255, 255, 255)):
self.a = a
self.b = b
self.rot_speed = rot_speed
self.spike_freq = spike_freq
self.color = color
def draw(self):
t = q5.frame_count / 60.0
pts = []
spike = math.pow(math.sin(t * 1.0), self.spike_freq * 2.0)
for k in range(N):
p = k / N * math.pi * 2.0
r1 = self.a * spike
r2 = self.b + r1 * math.sin(p * 10.0 - t * self.rot_speed)
x = r2 * math.cos(p)
y = r2 * math.sin(p)
pts.append((x, y))
c = set_saturation(self.color, min(0.8, spike))
q5.fill(*c)
q5.polygon(pts)
class App(q5.BaseApp):
def setup(self):
q5.title('2/1 #AltEdu2022')
# q5.set_loop_count(600)
self.nrows = random.randint(2, 7)
self.ncols = self.nrows
self.shape_grid = []
for i in range(self.nrows):
row = []
for j in range(self.ncols):
row.append(
Shape(
a=32.0*random.randint(1, 4),
b=200.0,
rot_speed=random.uniform(-20.0, 20.0),
spike_freq=random.randint(2, 10),
color=random.choice(palette)
)
)
self.shape_grid.append(row)
def update(self):
pass
def draw(self):
q5.background(220)
q5.stroke_weight(2.0)
for i, row in enumerate(self.shape_grid):
for j, shape in enumerate(row):
q5.push_matrix()
dj = 0.5 if self.ncols % 2 == 0 else 0.0
di = 0.5 if self.nrows % 2 == 0 else 0.0
q5.translate(
(j - self.ncols // 2 + dj) * q5.width / self.ncols,
(i - self.nrows // 2 + di) * q5.height / self.nrows
)
q5.scale(1.0 / self.ncols, 1.0 / self.nrows)
q5.stroke_weight(5.0 * self.ncols)
shape.draw()
q5.pop_matrix()
# t = q5.frame_count
# q5.save_frame(f'frames/{t:05d}.png')
if __name__ == '__main__':
app = App()
app.run()