Twenty-one lines grown outward from a circle, splitting whenever they drift too far apart.
Grow outward, split when crowded
The structure begins as twenty-one points on a circle of radius RadInitial and grows
outward in NumSteps rings, each ring slightly larger than the last:
var rad0 = Interpolation.Remap(ii, 0, NumSteps, RadInitial, RadFinal);
var rad1 = Interpolation.Remap(ii + 1, 0, NumSteps, RadInitial, RadFinal);
Every point steps out to the next radius and draws a segment. If the gap to its
neighbour has grown beyond SplitDist, a new point is inserted between them, and from
that ring onward there is one more gill.
The innermost rings. Twenty-one seeds, each nudged from its exact angle by
SeedJitter — enough to stop the first splits happening simultaneously all the way
round.
Why splitting is the only way to keep the spacing
Circumference grows linearly with radius. Twenty-one lines on a circle of radius 10 sit
three units apart; the same twenty-one at radius 90 would sit twenty-seven units apart,
and the drawing would be a sparse fan.
Splitting fixes the spacing instead of the count. Because the threshold is a distance,
the number of gills must roughly track the circumference — which is to say it roughly
doubles every time the radius does — and the finished count is a consequence of
RadFinal / SplitDist rather than a parameter anyone set.
This is exactly what real gills do, and for the same reason: a fixed spacing is what
the spore-bearing surface needs, and the only way to hold it while growing is to
interpolate new gills.
A third of the way out. The first splits are visible as short lines starting between
two established ones.
Splits insert, they do not fork
A split does not divide an existing line into two. It inserts a new line between two
neighbours, starting at that ring and continuing outward on its own.
The visual difference is significant: a forking gill would produce a Y, and the drawing
would read as branching. An inserted gill starts from nothing in the middle of a gap,
and the drawing reads as growth — which is what a mushroom’s gills actually look like.
Half.
Three quarters. The lines are still evenly spaced, and there are several times as many
of them as there were at the centre.
Smoothing
public float LerpFraction { get; init; } = 0.01f;
Each ring pulls every point slightly towards the midpoint of its two neighbours — one
per cent per ring, applied 175 times. That is a diffusion, and it is what stops the
lines wandering: a gill that drifts is nudged back into line with its neighbours a
little on every step, so the field stays combed without any line being told where to
go.
All the way out.
Five renderings
| Rendering | Seeds | Rings | Split distance | Ink |
|---|
| Electric Pink | 21 | 175 | 14 | pink on black |
| Toxic Lime | 18 | 175 | 14 | lime on near-black |
| Arctic White | 13 | 175 | 20 | white on black |
| Deep Violet | 30 | 200 | 9 | violet on near-black |
| Solar Amber | 19 | 175 | 13 | amber on near-black |
The variants explore different structural regimes. Arctic White uses fewer seeds and
a wider split threshold, so the gills stay sparse throughout and each one is prominent.
Deep Violet uses more seeds, more rings, and a tighter threshold, producing a much
finer and denser texture. Solar Amber extends the outer radius so the gills grow to
the edges of the canvas rather than stopping in the middle.
SplitDist is the parameter that decides gill count, and through it the density of the
whole drawing. Halving it roughly doubles the count at every radius.
Determinism
SeededRandom — the project’s stable Xoshiro256StarStar — is seeded from the preset
and consumed for the initial angle jitter and for whatever the growth needs, ring by
ring. Same seed, same gills.