Concentric rings and square frames on a grid, with every frame nudged off centre by its own random offset.
A grid of stacks
Each cell of a square grid holds two concentric stacks on the same centre: rings at
one pitch, frames at another. Both reach the same outer extent, because both pitches
are the cell size divided by twice the count:
float circleStepSize = CellSize / (2 * CircleSteps);
float squareStepSize = CellSize / (2 * SquareSteps);
Eleven rings against nine frames over the same distance. That mismatch is inherited
from the unoffset version of this piece, and on its own it produces a regular
interference between the two families.
Two steps out. At this size the two stacks agree closely enough that they look like
one.
The offset
What separates this piece from its ancestor is one pair of lines:
float offsetX = (float)((rand.NextDouble() * 2 - 1) * randomness * offsetAmount);
float offsetY = (float)((rand.NextDouble() * 2 - 1) * randomness * offsetAmount);
Every frame — not every cell, every frame — gets its own random offset, drawn
uniformly from ±randomness × offsetAmount. At the default that is ±10 units in each
direction, against frames that range from about 15 units across at the innermost step
to 267 at the outermost.
So the offset is a constant in absolute terms and a shrinking fraction of the shape
it displaces. The innermost frames are thrown around by half their own width; the
outermost are barely nudged. The stack therefore reads as though it settles as it
grows — a wobble at the centre resolving into order at the edge — which is the
opposite of what “randomness” usually looks like when it is applied to a drawing.
The rings get no offset at all. They stay exactly concentric, which is what gives
the eye a fixed reference to see the frames wander against.
Four steps. The frames are still close enough to the rings to read as a pair.
Six, and in the renderings that draw frames the displacement is unmistakable —
particularly at the corners, where a frame that has moved diagonally breaks the
symmetry of its own cell.
Eight. The outer shapes of neighbouring cells have started to meet. Because the grid
pitch is exactly the extent, the outermost ring of one cell is tangent to the
outermost ring of the next; the frames, being both larger at the corners and
displaced, cross into their neighbours.
Full extent.
What each rendering draws
ShapeType decides which families appear: 0 for rings only, 1 for frames only,
2 for both. It is the one setting that changes what the piece is rather than how
it looks, and the renderings span all three of its values.
| Rendering | Grid | Cell | Shapes | Steps | Stroke | Randomness | Seed | Inks |
|---|
| Coral Glow | 3×3 | 800/3 | rings + frames | 11 + 9 | 2 | 0.5 | 42 | #FF6B6B / #FFFFFF on #050505 |
| Ember | 2×2 | 400 | rings + frames | 9 + 7 | 2.5 | 0.6 | 202 | #FF8C42 / #FFC857 on #170A07 |
| Graphite | 6×6 | 800/6 | rings + frames | 7 + 5 | 1 | 0.45 | 500 | #9BA3AC on #121212 |
| Lime Warp | 2×2 | 400 | rings + frames | 15 + 9 | 2.5 | 0.8 | 123 | #CCFF00 on #1a1a2e |
| Medallion | 1×1 | 800 | rings + frames | 12 + 8 | 3.5 | 0.7 | 9 | #C792EA / #F2A6C0 on #1B0F2E |
| Orbit | 4×4 | 200 | rings only | 15 | 1.5 | — | 99 | #FFFFFF / #7D96FF on #0B0B14 |
| Paper | 3×3 | 800/3 | frames only | 9 | 2 | 0.35 | 7 | #1F1D1A / #D9463C on #F4F0E6 |
| Teal Drift | 4×4 | 200 | rings + frames | 11 + 9 | 1.5 | 0.7 | 77 | #00CED1 on #0d0d0d |
The renderings are chosen to disagree on as much as they agree on. The grid runs
from Medallion’s single cell to Graphite’s thirty-six; the stroke from a hairline to
3.5 units; the ground from near-black through indigo, umber and plum to Paper’s
light ground. Lime Warp carries the widest offset of the set — its maximum offset is
0.8 × 36 units, against Teal Drift’s 0.7 × 20.
One thing they all agree on is the canvas. The lattice is square and the canvas is
not, and every rendering sizes its cells so the grid spans the 800-unit canvas
height exactly — GridSize × CellSize = 800 — so the outermost shapes of the top
and bottom rows sit on the canvas edges, tangent rather than cropped. The 1280-unit
width leaves even margins on both sides, and that ground is deliberate: it is the
wall a square plate earns on a 16:10 canvas, not unused space.
Orbit draws no frames, so nothing in it is offset at all — the offset squares of
the title do not apply to that rendering. Its raised ring count puts it closer to a
pure moiré study. Paper is the opposite corner in two ways at once: frames only,
and the sole light-ground rendering. Teal Drift keeps both families but pushes the
drift itself: sixteen cells, and small enough shapes that the displacement
dominates.
Inks
A preset paints with either one ink or a palette. With one ink, every shape draws in
the same colour. With a palette, the inks cycle across the steps of each cell —
step i draws palette[(i − 1) mod n] — so the stacks band in two colours and the
piece picks up a second, quieter voice. The banding is per step, not per cell or per
family: ring i and frame i always share their ink, which keeps the two families
locked together as the colours alternate. Five renderings band a two-colour palette;
Graphite, Lime Warp and Teal Drift draw a single ink each.
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 lead preset, Coral
Glow, 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 none of the other renderings gets a framed copy.
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 museum canvas keeps the piece’s
own 16:10 aspect, so the opening matches the artwork’s canvas exactly: the
artwork fills the opening edge to edge, and its outermost shapes — which sit
on the artwork’s own top and bottom edges — are clipped at the mat like a
full-bleed print behind glass. The frame knows nothing about rings, offsets
or grids, and the artwork knows nothing about being framed.
Determinism
One Random is created per draw, seeded from the preset, and consumed frame by
frame in row-major order over the grid. Every offset is therefore fixed by the
seed. The generator is System.Random, which the project’s determinism policy flags
as not guaranteed stable across .NET versions.
A rendering that draws rings only never consumes the generator, so Orbit’s seed has
no effect on anything.