[generator] — for star_pattern
| Key | Values | Notes |
|---|---|---|
tiling | square/4/4.4.4.4, hexagon/6/6.6.6, octagon/8/4.8.8, dodecagon/12/3.12.12, none | Star order n. Required. none draws no interlace at all — the rings-only mandala below — and is a load error unless rings has at least one entry, because a preset with neither draws nothing. |
contact_angle_deg | number | Hankin contact angle. Default 30. Inert at tiling = "none". |
rings | array of ring tables (below) | The mandala interior. Optional — absent is the Hankin interlace alone, segment for segment. |
rings — concentric rings of repeated motifs
The answer to star_pattern reading as a hollow ring. Each entry is one
concentric ring; copy i of a ring of k sits at angle 2*pi*i/k + phase, at
radius from the frame centre, scaled by scale. Motifs are drawn through the
same line renderer as the interlace, so the stroke, joins, glow and palette are
the ones you already know.
| Key | Values | Notes |
|---|---|---|
motif | one of the eight names below | Required. An unknown name is a load error listing the legal set — the roster is closed, not extensible. |
count | 1 .. 512 | Required. Copies around the ring. 0, a negative, or anything over the ceiling is a load error. |
radius | number | Required. Distance from the frame centre, in the fit-normalized world the figure lands in: it spans +/- 0.9, so 0.9 is the rim and anything smaller is interior. 0.0 is a single centre boss. |
scale | number | Motif size multiplier — close to the copy’s diameter, since every outline spans about one unit. Default 0.25. |
phase | number (radians) | Angular offset of copy 0. Default 0. Use it to stagger a ring against its neighbours. |
scallopreads three of those keys differently, and it is the only member that does. It is a boundary, not a bead repeated around a ring, so there is no copy count:countis its lobe count (floored at 3 — below that there is no boundary, and a smaller number is raised rather than refused),radiusis the base circle its lobes bulge from, andscaleis the depth of the bulge, which is the only size a lobe has oncecounthas fixed its width.phaseturns the whole boundary, as it turns every other ring. Each key keeps its spirit; none of them means a copy.
The closed motif roster is eight names, every one picked from rendered
samples, and closed on purpose: a look outside it routes back through architect + dev, it is not a
preset-side extension point:
motif | what it is | instances per copy |
|---|---|---|
circle | a plain bead; the ring that reads as a dotted orbit | 1 arc |
petal | a pointed oval (vesica), cusped at both ends along the radius | 22 arcs |
teardrop | round outward, cusped inward — the only motif with an unambiguous “which way is out” | 16 arcs |
diamond | a four-vertex rhombus, long along the radius | 4 |
arc | an open outward-bulging arc, chord tangential; the nearest this roster comes to a scalloped boundary | 1 arc |
trefoil | a three-lobed rose — the densest member, and the one that reads as ornament rather than as a bead | 24 arcs |
chevron | an open two-segment wedge, apex outward; a sawtooth border at high counts | 2 |
scallop | the scalloped boundary — one closed chain of outward-bulging arcs meeting at cusps. Not a bead: see the key note above | 1 arc per lobe |
Six of the eight are drawn as real curves (ADR-0098) — only
diamondandchevronare still sampled polylines — and the two circular ones are the cheapest members of the roster. Every arc’s stroke is a distance evaluated per pixel, so it has no vertices at any scale.
circleandarcare exact, one instance each, with no interior joint at all. Where acirclecost 24 segments and 24 additively-overlapping joints, it costs one instance and none.petal,teardropandtrefoilare fitted G1 chains — 22, 16 and 24 arcs, against the 24, 24 and 36 segments they were. Consecutive arcs share a tangent, so a chain has no corner where its pieces meet; what it does keep is the figure’s own corners, which is why atrefoilstill cusps three times and ateardroponce. Three tangent breaks where there were 36 is the remaining bead count, and it does not depend on the scale you draw at.scallopis exact and needs no fit at all — a scallop is a chain of circular arcs, which is what makes it a scallop and not a sine wave. Atscale = 0every lobe is an arc of the base circle, so the boundary is a plain ring: sweepingring_scalethrough zero passes through that rather than through anything undefined.diamondandchevronstay sampled polylines, which is the right primitive for them: a distance field is strictly more expensive for a straight line, and these two are nothing but straight lines.
starandtrianglewere cut at the same sitting and are load errors now. The property they were cut on is the one to judge a candidate by: does it hold its identity across the whole 8-to-32 count range.staris an ornament at ×8 and dissolves into texture by ×32;triangleduplicateschevron’s role at twelve times the cost.
The instance budget, and what happens when you exceed it. A ring costs
count × instances-per-copy, and the interlace adds 2n on top. Segments and
arcs share one ceiling — 20 000 at the floor tier, 60 000 at rich — so the
four-ring mandala roster at 24 + 12×4 + 18×22 + 24×1 = 492 plus a 24-segment
interlace uses under 3 % of it. (Drawn as sampled polylines instead, the same
roster would cost 1 092 — its circle ring alone is 576 segments against 24
arcs.) Two things to know:
- Truncation at the cap is silent. The build stops emitting and nothing warns
you — no load error, no
--reportcolumn. The figure simply ends part-way through a ring, in roster order, so it is the outermost rings you lose. If a dense mandala looks like it is missing its outer ring, count your segments. - There are two ways to exhaust the same cap. The interlace grows with the
tiling and the rings grow as
rings × count × resolution; the failure looks identical from either direction.
The three bindable levers (ring_phase, ring_spread, ring_scale) move this
roster without changing what is in it — see
the ring levers.
system = "star_pattern"
[generator]tiling = "none" # the ornament alone; "12" composites it inside the interlacerings = [ { motif = "trefoil", count = 1, radius = 0.00, scale = 0.46 }, { motif = "diamond", count = 12, radius = 0.30, scale = 0.20 }, { motif = "petal", count = 18, radius = 0.52, scale = 0.26, phase = 0.09 }, { motif = "circle", count = 24, radius = 0.70, scale = 0.13 }, # count = lobes, radius = the circle they bulge from, scale = the depth. { motif = "scallop", count = 40, radius = 0.86, scale = 0.05 },]
scallopis the boundary motif;arcis not. A ring of 40 overlappingarcmotifs faking a continuous edge was judged against a real scalloped boundary and lost.arcis an open arc; reach forscallopwhen you want a boundary.
The ring levers — and why two of them are radial
| Param | Default | What it does |
|---|---|---|
ring_phase | 0 | Turns alternate rings in opposite directions, in radians: ring 0 by +phase, ring 1 by −phase, and so on down the roster. Counter-rotation is the strongest ornamental gesture this geometry has. Wraps at one turn. |
ring_spread | 1 | Multiplies every ring’s radius about the centre — the figure opening and closing. Clamped to 0 .. 4. |
ring_scale | 1 | Multiplies every motif’s scale — the copies growing in place, without moving the rings. On a scallop ring that is its lobe depth, so the boundary breathes between a plain circle and a deep scallop. Clamped to 0 .. 8. |
All three default to the exact identity, so a preset that binds none of them
draws the roster it declared, and one that declares no rings is untouched by
their existence.
Do not carry a mandala’s animation on
ring_phasealone. A ring mandala is very rotationally symmetric — an 18- and 24-fold figure turned by any angle lands almost on top of itself — so a spin moves few pixels however fast it runs, and both the eye at a distance andcore/tests/animation.rsread it as frozen.ring_spreadandring_scalechange what the figure is at each radius rather than where it points, so they are what actually carries the motion. Spendring_phaseon the gesture and the radial pair on the liveness.
A mandala that must hold up in a portrait window carries a narrower
scaleorzoom. The shared line renderer divides world x by the target’s aspect, so at 720×1280 a figure is 1.78× wider in NDC than it is tall: a radius-0.62 ring that fits comfortably at 16:9 runs off both sides in portrait. This is an authoring fact rather than a defect — the three shipped mandalas are sized for a landscape window and do graze the frame in portrait.
Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.