ContributorMural::Renderers::Pebble
Inherits ContributorMural::Renderer < Reference < Object
A pile of stones: everyone is a disc sized by their rank, poured into a slab and shaken until nothing overlaps. The only style that does not fill its rectangle — the page shows between the pebbles, which means it themes itself for free the way voronoi's lead does.
The pack is a relaxation rather than a formula. Discs start on a jittered
lattice across the slab, and then every sweep pushes overlapping pairs
apart, carries the whole pile a step toward the slab it is aimed at, and
holds it inside. width caps how wide the slab may be and density says
how much of it the pebbles cover; between them they decide how tall the
pile comes out.
Constants
One clip for the whole document: the image box is exactly the disc's bounding square, so the unit circle is the pebble.
How much the slab grows, and how many times, when the pack cannot settle inside the one it was given.
A density is a request, and whether it can be met depends on the crowd:
the same figure that packs cleanly at forty people jams at eight, where
there are too few discs for the edges not to dominate. Rather than pick
the one figure that survives every crowd — which would be well below what
looks good for the crowds people actually have — the pack loosens and
tries again. Six goes at eight percent give the slab half again the room,
enough to carry the tightest density the config allows down to where it
settles, so "no two pebbles overlap" holds for every config rather than
for the ones that happened to get tested.
How much of the way toward the slab each sweep carries the pack. Small enough that the separation keeps up with the stretch, large enough to arrive well inside the sweep budget.
Breathing room around the finished pile, so a pebble on the edge is not flush against the document bounds.
Disc-sweeps a section may spend before the sweep count gives way. Reached at about three thousand people; below that the step count is fixed.
Sweeps of separate-fit-hold, then a tail that only separates and holds. The tail is what makes "no two pebbles overlap" true rather than nearly true: the fit runs after the separation in every sweep, so the last thing to happen to the pack would otherwise be a squeeze that can push a pair back together. It leaves as soon as a sweep finds nothing worth moving, so its cap is a backstop rather than a cost.
An overlap smaller than this is left alone, and a sweep that found nothing bigger counts as having settled. Without a floor the pack never stops: every sweep finds a pair a few millionths of a pixel inside its clearance, pushes it out, and nudges two more in — so the settle runs to its cap every time and the whole style comes out orders of magnitude slower than the rest. Coordinates are written to two decimals, so this is three decimals below anything a reader could see.
Voronoi's salt multiplier, in the same role: keeps one section's jitter from repeating in the next.
How wide the pile wants to be against how tall, before width caps it.
A mural sits above or below a README's prose, so it wants to be a band;
much past this and a small crowd reads as a scattered line rather than a
pile.
Two centres this close have no direction to be pushed along.
Instance methods
The image box is exactly the drawn diameter and the clip is inscribed in it, so unlike voronoi — where a heavy cell runs wider than its nominal pitch — nothing here outgrows the size it was fetched for. Plain 2x for high-DPI is exact.
Dense rank over the distinct weights, as voronoi does, so a contributor with 1000x the commits lands at the top of the taper exactly like one with 2x. Where voronoi leaves the table empty for an all-equal crowd, this fills it at full size: a rank of zero would read as "smallest pebble", and no ranking information should mean a uniform field, not a field of minimums.