def g02_flowfield(rng):
"""FLOW FIELD — one segment per cell, angle from a summed sine field,
weight from the field's rate of change. Fast-turning regions go heavy."""
N = 40
c = Canvas(N, "GEOMETRIC", "lines", "flowfield", tiles=False)
C = c.C
k1, k2 = rng.uniform(1.5, 4.0), rng.uniform(1.5, 4.0)
sw_ = rng.uniform(0.4, 1.6)
off = rng.uniform(0, math.tau)
def theta(u, v):
return (math.sin(u * k1 * math.tau + off) * 1.4
+ math.cos(v * k2 * math.tau) * 1.1
+ math.sin((u + v) * sw_ * math.tau) * 0.8)
L = C * rng.uniform(1.15, 1.75)
for i in range(N):
for j in range(N):
u, v = (i + 0.5) / N, (j + 0.5) / N
a = theta(u, v)
d = abs(theta(u + 1.0 / N, v) - a) + abs(theta(u, v + 1.0 / N) - a)
w = 0.06 + 0.34 * clamp(d * 3.0)
x, y = c.center(i, j)
c.line(x, y, L, math.degrees(a), sw=w * C, cap="round")
return c