def g50_shear(rng):
"""Shear — the ground is read through a row offset that grows down the canvas.
Each row samples the field at a horizontally displaced position, so a smooth
gradient arrives as a raked, slipped surface. A sparse overlay of half-width
bars marks the rows where the slip is steepest.
"""
steps = rng.randint(5, 8)
N = rng.choice([30, 40])
c = Canvas(N, rng.choice(PALETTE_NAMES), steps, "shear", "squares")
f = Field(rng, "mesh", warp=rng.uniform(0.1, 0.3), steps=steps)
f.calibrate(N)
rake = rng.uniform(0.4, 1.4)
bend = rng.uniform(-1.0, 1.0)
def slip(j):
t = j / N
return rake * t + bend * t * t
c.ground(lambda i, j: f.idx(((i + 0.5) / N + slip(j)) % 1.0, (j + 0.5) / N))
C = c.C
for j in range(N):
d = abs(slip(j) - slip(max(0, j - 1))) * N
if d < 0.55:
continue
for i in range(0, N, 2):
u = ((i + 0.5) / N + slip(j)) % 1.0
c.sq(i * C, j * C + C * 0.25, C, C * 0.5, (f.idx(u, (j + 0.5) / N) + 3) % steps)
return c