Two paths turning by a constant angle and stepping a little further each step, interleaved half a pitch apart into a braid, drawn with a pen almost as wide as the groove it leaves.
Two accumulators
There is one moving point and two numbers that only ever increase:
heading += AngleStep * (MathF.PI / 180f);
length += LengthIncrement;
heading turns by a constant eight degrees per step. length — the step length — grows by a
constant 0.12 units. Neither ever resets, and neither depends on the other.
Four hundred and twenty steps of that, run twice — once per arm — is the whole piece.
Forty-two steps: not quite one revolution of each arm. The step length here is between one
and six units against a pen twelve pixels wide, so consecutive marks overlap almost
completely and each arm reads as a ribbon rather than as a line — and because the second
arm left the centre on the opposite heading, its ribbon already rides half a pitch
outside the first, the two never crossing.
Constant turn, growing step: a spiral with constant pitch
Turning by a fixed angle δ and stepping a fixed length traces a polygon
approximating a circle of radius L / (2 sin(δ/2)). Let the length grow linearly and
the radius grows linearly with it, which is the definition of an Archimedean
spiral — equal spacing between successive windings, all the way out.
For this rendering the arithmetic is:
steps per revolution = 360 / 8 = 45
length gained per rev = 45 × 0.12 = 5.4
radius gained per rev = 5.4 / (2 sin 4°) ≈ 38.7 px
So every winding sits about 38.7 pixels outside the one before it, from the first
revolution to the last.
A quarter of the walk. The windings have separated far enough to be counted, and the
second arm’s are settling into the first’s grooves.
A heading offset is a radius offset
This is the detail that turns a spiral into a braid. The spiral’s radius is linear in
its accumulated angle — r = a + bθ is the definition of Archimedean — so two walks
that leave the centre on different headings are the same walk shifted in radius. The
second arm here leaves 180° behind the first, which is exactly half a pitch further
out: its every winding falls in the first arm’s groove, violet into pink, and the two
threads interleave without ever crossing a neighbour’s winding.
The same identity generalises: three arms 120° apart sit a third of a pitch apart,
five arms 72° apart a fifth. The presets below are built on it.
The pen is almost as wide as the groove
The stroke is 12 pixels and the threads sit 19.4 apart — half of the 38.7 pitch
— so the two arms very nearly touch, leaving a groove a little over seven pixels wide
between them. The whole braid is therefore two solid ribbons cut by a fine spiral of
background, and that cut is not drawn. It is the space the pen failed to cover.
Change either number and the character goes, and each preset sits at a different point
on that trade:
| Rendering | Angle | Increment | Stroke | Pitch | Groove |
|---|
| Fialový Braid | 8° | 0.12 | 12px | ~38.7 | ~7.4px between two threads |
| Rosette Ice | 8° | 0.12 | 5px | ~38.7 | ~2.7px between five threads |
| Paper Ink | 8° | 0.12 | 12px | ~38.7 | ~26.7px — wider than the stroke |
| Octagon Jade | 45° | 0.50 | 4px | ~5.2 | ~1.2px — a hairline between nested octagons |
| Sunset Silk | 8° | 0.12 | 9px | ~38.7 | ~3.9px between three threads |
Sunflower Gold leaves the trade entirely: it turns by the golden angle — 137.5°, which
no circle ever closes — and paints each vertex as a dot instead of stroking the chords
between them, so the walk reads as a stippled phyllotaxis lattice, dense and merged at
the centre and beaded into spiral families further out.
Halfway: four and two thirds revolutions in. The braid is set.
Three quarters. From here the geometry adds nothing new — the pitch is constant and
each revolution looks like the last — and what distinguishes the windings is the
colour.
The colour jitter
Each segment takes its own colour, drawn as the arm’s base shifted by up to ±50 in
each channel:
byte r = (byte)Math.Clamp(fr + rng.NextInt(-50, 50), 0, 255);
That is the only random content in the piece, and it has no effect on the geometry.
Because the range is clamped, a channel already at 255 can only move down and one at
0 only up, so a saturated foreground drifts towards pastel rather than towards a
different hue — which is why each thread stays banded in its own violet, never
drifting into the other’s pink.
Four hundred and twenty steps: about nine and a third revolutions, the outermost
winding near 366 pixels from the centre on an 800-pixel canvas.
The fit
Where on the canvas the walk sits is not left to the knobs. Before anything is
stroked, the finished walk’s ink is measured — the bounding box of all
Iterations vertices of all arms, expanded by half the pen — and the canvas is scaled and
centred so that ink fills the frame minus a border of FitMargin (4% of the
side, 32 pixels here), the tighter axis binding. The braid lands at 1.01× — nearly
native — while the family spreads from Paper Ink at 0.73× to Sunflower Gold at 14.5×:
six walks of very different natural sizes, presented at the same deliberate margin.
This is presentation, not generation. Every vertex and every colour is what the
accumulators produced; the fit only chooses the frame. And because the
frame is computed from the finished walk, a shorter walk draws inside the
finished walk’s frame — the stages above are the piece caught growing into a
frame that never moves, which is why they are strict prefixes of the last
plate.
The museum plate
The gallery’s closing plate presents the finished walk as a hung work: on a
dark gallery wall, behind an ivory mat and a thin dark frame, under a drop
shadow, with a hairline of the piece’s own violet where the mat meets the
artwork and a brass plaque below. The plaque carries no lettering — typefaces
are not deterministic across machines — so it bears the piece’s signature
instead: the walk itself, in miniature, fitted to the plaque exactly as the
piece is fitted to its canvas.
MuseumFrame is a presentation layer around the piece, and the separation is
strict: the frame knows nothing of the walk’s arithmetic, and the walk knows
nothing of frames. One plate, not one per preset — the frame is a way of
showing the finished piece, not a family of renderings. The samples and the
steps stay bare.
Determinism
SeededRandom — the project’s stable Xoshiro256StarStar — is seeded from the
preset and consumed three times per step, arm by arm and step by step. The geometry
consumes nothing: it is a pure function of the angle step, the length increment, the
iteration count, and the arm layout.
The fit and the frame draw from the same contract. Both are pure functions of
the walk’s geometry and the declared palette — no RNG, no clock, no typeface —
so the framed plate is as reproducible as the samples.