A buried coffin, and thirty roots that walk downward around it under a gravity that keeps pulling them straight.
Above and below
The composition has a horizon and two different kinds of drawing on either side of it.
Above is geometry: a dashed ground line and, in most presets, a bark-textured trunk
running to the top edge. Below is growth, and whatever obstacle — if any — is buried
in it.
DrawDashedLine(canvas, paint, TopH, 100);
foreach (var obs in Obstacles)
obs.Draw(canvas, paint);
Everything is drawn through direct line calls to the canvas — one explicit segment at a
time — which is why the whole piece reads as one continuous pen even where the subjects
are unrelated.
The setting, with no roots yet. When a trunk is present, sixty short marks scatter below
the ground line as soil texture, placed by three chained coin flips that bias them
towards the left wall, the right wall, or anywhere between:
if (rng.NextDouble() <= 0.25) x = -SourceR;
else if (rng.NextDouble() <= 0.33) x = SourceR - dd;
else x = -SourceR + (2f * SourceR - dd) * (float)rng.NextDouble();
A quarter cling to the left wall; of the rest, a third cling to the right; the
remainder float. That three-way split is what stops the marks reading as uniform
noise.
Thirty roots, evenly spread and not
float angle = 180f / (RootCount + 2f) * (1f + i + (float)rng.NextDouble() - 0.5f);
The angles divide a half-circle into RootCount + 2 slots and give root i slot
i + 1 — so the fan is regular, and the two end slots are left empty so nothing grows
horizontally along the surface. The rng.NextDouble() − 0.5 term then nudges each
root by up to half a slot.
That is the difference between a fan and a diagram. Perfectly spaced roots look
mechanical; a half-slot of jitter is enough to break the regularity while keeping the
spread even.
A quarter of the roots. Each begins within a unit or so of the coffin’s edge and
grows away from it.
A root is a walk, not a curve
No root is planned. Each is a biased random walk: step forward a short distance,
perturb the heading by a Gaussian, then pull the heading back towards straight down.
Repeat until the length runs out, branching occasionally on the way.
The two forces are the whole character of the drawing. Without the jitter the roots
would be straight lines; without the gravity they would wander off sideways and never
descend. Together they produce the thing that reads as root rather than as crack: a
line that is always going down and never going down directly.
The Gaussian is generated by Box–Muller rather than by summing uniforms:
return mu + sigma * MathF.Sqrt(-2f * MathF.Log(u)) * MathF.Cos(2f * MathF.PI * v);
Two uniforms in, one normal out — exact rather than approximate, which matters because
it is the tail of that distribution that produces the occasional root that swings wide.
Half.
Three quarters. The roots part around the coffin — not because any of them tests for
it, but because the ones aimed at it are deflected, and the gap that leaves is the
coffin’s shape. Roots do not avoid each other at all: where two cross, they cross.
All thirty.
Renderings
| Rendering | Roots | Ink | Obstacle |
|---|
| Lime Roots | 30 | neon green on black | coffin |
| Chalk Veins | 22 | near-black on warm cream | coffin |
| Coral Tendrils | 35 | coral on near-black | coffin |
| Cobalt Veil | 50 | pale blue on near-black | coffin |
| Amber Drift | 16 | amber on near-black | coffin |
| Open Roots | 45 | teal on near-black | none |
| Wedge Block | 25 | gold on dark warm | single triangle |
| Stone Garden | 35 | pale cyan on near-black | five triangles |
| Slab | 28 | burnt orange on near-black | flat rectangle |
Each has its own seed, so the renderings are independent growths. RootCount changes
both the number of roots and the angular spacing between them, since the slot count is
derived from it — so a denser rendering is not the same fan with more in it.
The obstacle a root encounters changes its visible path. A coffin creates a gap shaped
like the buried object; a triangular wedge splits the curtain into two streams that
curve around its slopes; a flat slab parts the roots left and right along a hard
horizontal line; no obstacle at all lets each root wander freely until gravity alone
decides where it lands.
Museum Frame
Lime Roots presented as a finished piece. A 100-pixel gallery mat in warm neutral gray
surrounds the same 800 × 800 artwork on a 1000 × 1000 canvas, with a thin frame line
at the mat boundary. The framing is a presentation layer over the unchanged generative
design — the same seed, the same thirty roots, the same ink.
Origin
Inspired by the Turtletoy sketch at
turtletoy.net/turtle/ad4a6ed109. The core
biased-random-walk idea — step, jitter heading, let gravity pull back toward vertical —
carries over directly, while the obstacle system and source configurations are new.
Determinism
One Random is created per draw, seeded from the preset, and consumed in a fixed
order: the sixty soil marks first, then per root an angle jitter, a start position, and
whatever the recursive growth needs. The generator is System.Random, which the
project’s determinism policy flags as not guaranteed stable across .NET versions.