Skip to content
Русский

Two coordinates — offsets and scaled copies

coord_mode decides what a band of the palette is a band of. Both coordinates are 0 at the figure’s centre and exactly 1 on its outline; what differs is everything in between (ADR-0111).

coord_modethe coordinatea contour is
"0" (default)the normalized distance to the figurean offset of the outline
"1"r / r_boundary(theta) — how far out you are as a fraction of the outline in that directiona scaled copy of the outline

The difference is not a nuance on the shapes with a corner. An inward offset is an erosion, and erosion rounds a reflex corner while keeping convex ones sharp — so under "0" a nested heart keeps its bottom point and loses its top notch as the rings move inward, and no value of gamma or palette_steps recovers it. Under "1" the inner figures are the same figure, smaller.

How many interior bands a figure can take is set by its thinnest feature, not by its overall size. Erosion eats a thin feature entirely before it has touched a broad one, so the band count is a question about the narrowest part of the silhouette and about nothing else. The cases that are measured: at three interior bands a koi’s fins and tail were eaten and the figure read as a lumpy blob, and the retired Path Lion’s mane tufts went the same way — both settled at two. presets/shape_maple.toml carries three because its lobes are broad; it is not the sturdier drawing, it is the fatter one. Under "1" the question does not arise by construction: an interior contour there is a scaled copy, so a fin is still a fin at a smaller size rather than something the offset has consumed.

[params]
shape = "4" # the heart
coord_mode = "1" # <- nested SCALED COPIES rather than offsets
palette_steps = "9" # the ring count, and now nothing trades against it
gamma = "1.0" # spacing only; it no longer decides notch sharpness

color_span DOES NOT TRANSFER between the two modes, on top of the shape-to-shape trap the same parameter already has (above). Under "0" the exterior is divided by the shape’s inradius; under "1" it grows linearly in r. A preset that switches modes has to re-tune its span, and nothing warns.

"0" is the default and it is bit-for-bit the arithmetic that shipped, so no existing preset moves.

Which arms the mode actually changes, measured as how far a contour deviates from a scaled copy of the outline (0 means it is one):

shapeinside the figureoutside it
discidentical — its offsets and its scaled copies are the same circlesidentical
ringnot available — "1" is refused, with a load warning, and the distance is drawn. See belownot available
polygonidentical: eroding a regular polygon moves every edge in by the same amount, and erosion rounds only reflex cornersdiffers — outside, the distance rounds each vertex into an arc
star, straight edgeidentical, for the same reasondiffers, 0.03..0.06
star, star_curve or star_jitter non-zerodiffers, 0.12..0.20differs
heartdiffers, and it is the whole point — 0.02 at the outermost of nine rings and 0.55 at the innermostdiffers

The heart row is the one to read. Its deviation under "0" grows as the rings move inward — that is the notch filling in, ring by ring — and under "1" it is 0.00000 at every ring. The disc is the control: an engine that drew those two differently would be broken.

coord_mode = "1" NEEDS A FIGURE EVERY RAY FROM ITS CENTRE LEAVES ONCE, and it tells you when it has not got one. r / r_boundary reads the outline’s radius along a ray from the figure’s centre, so a ray that crosses the outline more than once leaves the coordinate with no single value there. Two figures fail it, and they fail it in the same way:

  • a ring, whose centre lies in its hole — and any shape travelling towards or away from one, since a blend that has the ring on either side inherits its hole;
  • an authored [path] contour that is not star-shaped about its centre — a crescent, a figure with fins, or a silhouette whose sinuses put one lobe across the ray into the next. presets/shape_maple.toml is one: its four deep sinuses put a neighbouring lobe across the ray, and it measures a worst ray gap of 0.40 against a tolerance of 0.02. It ships under "0", so nothing about it moves — but write "1" on it and you get the warning.

On both the scene draws the distance instead, and it warns at load when the preset rests on the combination — a shape that only travels through the ring’s neighbourhood gets the fallback in silence, because a resting value is all the loader can see:

parameter 'coord_mode' is ignored on a `ring`: an annulus's centre lies in its
hole, so a ray from there crosses the outline twice and the scaled-copy
coordinate has no single value there. The figure is drawn with the distance
instead — a band of constant distance rather than a scaled copy of the outline

Concavity on its own is not the problem, and a check that convicted it would be useless: a deep five-pointed star has five reflex corners and every ray from its centre still leaves exactly once, so it takes "1" in silence. What matters is whether any part of the figure hides another part from its own centre.

The alternative on the ring was to define the boundary as the outer rim, and it was rendered before being rejected: the coordinate then collapses to length(p) and the ring comes out byte-identical to a disc — the hole simply stops existing. Naming one shape and being shown another is worse than being told no.

On the roster the warning only fires on a shape that rests at ring. A binding that animates through it rests nowhere, so nothing warns; the fallback still applies, frame by frame. An authored contour cannot animate, so there the warning always fires when it applies.

rotation turns the figure about its own centre — and kaleido_* is not the same thing. The screen-space fold folds the finished frame about a screen-centred axis; it does not turn the figure, it multiplies it, and it fights a translating pan_* (a panned figure comes out decentred in the rosette). If you want the figure to turn, reach for rotation.

[params]
pan_x = "0.35"
rotation = "time * 0.4" # a slow turn IN PLACE, not an orbit

The after the pan part is the choice worth knowing: the turn is applied to the figure’s own frame, so a panned figure spins where it sits. Turning before the pan would swing it around the frame’s middle on a circle of radius |pan|, which is a different look and is not what this does. The angle is in radians, matching rotation on star_pattern and lsystem, so multiply by time yourself.

There is no zoom here and that is not an omission: scale is this scene’s size lever, and a view zoom on top of it would be a second spelling of one idea.

Built from 13c7582 at version 0.158.0. This site tracks main and is not versioned per release.