Nine centres, each carrying a stack of rings and a stack of frames, fading as they grow.
Two stacks on nine centres
The composition is a three-by-three grid of centres — the page centre plus a
lattice offset — and at each one the piece draws two independent families of
concentric shapes:
var ring = new SKPath();
ring.AddCircle(point.X, point.Y, radius);
var outline = new SKPath();
paint.GetFillPath(ring, outline);
outline.Transform(SKMatrix.CreateTranslation(origin.X, origin.Y));
canvas.DrawPath(outline, fill);
foreach (var (corner, size) in MathHelper.Concentric(point, StepSizeBySquare, StepsBySquare))
canvas.DrawRect(origin.X + corner.X, origin.Y + corner.Y, size, size, paint);
Eleven rings and nine frames, each placed on the page by an explicit translation of its
geometry. The ring is stroked while it still sits at its lattice point and only the
finished outline is moved to the page — Skia’s stroker rounds by the magnitude of the
coordinates it works on, so stroking at page coordinates would not reproduce the
committed pixels.
Both stacks reach the same outer extent, because the step size is defined as the
extent divided by the count:
public float StepSizeByCircle => Size / (2.0f * StepsByCircle);
public float StepSizeBySquare => Size / (2.0f * StepsBySquare);
So the two families agree at the outside and disagree everywhere else — eleven
divisions against nine over the same distance. That mismatch is the piece.
Two rings at each centre. At this point the drawing is a grid and nothing more.
The fade is the depth
Neither stack is drawn in one colour. Each shape is tinted by how far out it is:
paint.Color = Foreground.Lerp(Background, radius / (StepsByCircle * 2 * StepSizeByCircle));
At the centre the colour is Foreground; at the outer edge it has travelled all the
way to Background. The stacks therefore read as receding rather than as stacked,
and the outermost shapes are quiet enough that the cells do not fight each other
where they meet.
The frames use the same idea with a different measure — the horizontal distance from
the centre to the frame’s left edge, over the extent — so the two families fade at
different rates as well as at different pitches.
Halfway. The gradient is doing the work the line weight is not: the stroke is a
constant two pixels for every shape in the piece.
All eleven rings. The outermost has radius Size / 2, which is exactly half the grid
pitch — so the rings of adjacent cells are tangent, and never overlap.
The frames
The second family begins, on the same nine centres. Note what is already visible: a
frame’s corner reaches √2 times further than its edge does, so the squares break
out of the circle of tangency that the rings respect and run into their neighbours.
Both families complete. The interest is in the near-misses — a ring at k/11 of the
extent and a frame at j/9 of it coincide only at the outside, so everywhere else
they cross at angles that shift steadily from centre to edge.
The canvas is not the background
One detail that is easy to misread. The piece clears to white:
canvas.Clear(SKColors.White);
Background — purple, in this rendering — is never painted anywhere. It is used
only as the far end of the colour fade, so the shapes travel from red towards purple
against a white ground, and the ground itself is not either of the declared colours.
Reading the preset alone would suggest a purple field with red shapes; the picture
is a white field with red shapes turning purple as they grow.
Default preset
| Setting | Value |
|---|
| Grid | 3 × 3 |
| Extent | 700 |
| Rings | 11, step 700/22 |
| Frames | 9, step 700/18 |
| Canvas | 3840 × 2160 |
| Colours | red, fading to purple, on white |
The lattice is square and the canvas is not, which is where the composition’s
margins come from. The extent is chosen so the whole lattice — the outermost rings
of the edge cells included — fits the 2160-unit canvas height with about S/11 of
white above and below, the same gap adjacent cells keep between their outermost
rings. The page edge reads as another cell boundary instead of a crop. Horizontally
the same extent leaves about 900 units of white on either side — the wide wall a
square plate earns on a 16:9 canvas.
Variants
Four additional presets explore the generator’s range without changing the algorithm.
tight uses a 5 × 5 field of twenty-five centres — the same eleven rings and nine
frames per cell as the default, but at a smaller extent so the lattice fills the
same canvas. The pattern, which in the default reads as nine discrete objects, here
becomes a repeating surface, closer to textile than to a collection of forms.
open carries a single large centre: eleven rings and nine frames spread to the
full vertical height of the canvas, with no neighbours. Where the default’s cells
share their visual space, this one isolates the form — all the interference is
visible at once, without the grid to redirect the eye.
few returns to the 3 × 3 grid but reduces each family to five rings and four
frames. Five and four are coprime, so every ring-frame crossing is distinct, but
the small count means they are far apart and easy to see individually. The design
is architectural in tone — a few bold lines rather than a close texture.
many also uses the 3 × 3 grid, with twenty-three rings and seventeen frames.
Both numbers are prime, so no two crossings coincide across the full extent. The
fine step size compresses the interference into something close to a woven pattern,
where the individual crossings dissolve into overall texture.
The museum plate
The gallery ends with the piece the way it would hang on a wall. MuseumFrame
is a presentation layer, not a generative one: it takes any ISkiaArt piece,
clears to a gallery wall, and draws a frame, a mat with a bevel rule, and the
artwork contain-fitted into the opening behind them. The single rendering appears
in the gallery twice — once as the raw plate, once framed — because the frame is
a way of showing the work rather than a rendering of it, and there are no other
renderings to frame.
The proportions are fixed: the opening is 65% of the canvas in each axis, the mat
4% and the frame 2% of the shorter side around it, and the rest is wall with a
soft drop shadow under the frame. The artwork is clipped at the mat edge, and
because the piece clears to white, the opening shows the print’s own white border
around the composition — the mat never touches ink.
Determinism
There is nothing random here. Both stacks are arithmetic sequences of radii, the
nine centres come from a fixed grid helper, and the colours are linear
interpolations of two constants. Drawing order is centre by centre, rings before
frames, innermost first.