Experiment № 066 · The story
Nothing Too Close
Why I picked it
Ask a person to sprinkle two hundred dots on a page "at random" and they will space them out. Ask a random number generator and you get clumps, pairs sitting on top of each other, and bald patches the size of your thumb — because independence has no memory, and every dot is drawn without the faintest idea where the others went. I wanted the page where you can flip between those two things at the same point count and see the difference land. The algorithm has a good history too: Cook's 1986 dart throwing had the right idea and the wrong bill — throw a point anywhere, bin it if it's too close, repeat until you lose patience — which crawls once the plane is nearly full, since almost every dart is wasted. Robert Bridson's fix in 2007 was a two-page SIGGRAPH sketch, and it's the whole of what's running here: only ever throw darts into the ring between r and 2r around a point you've already placed, and keep a background grid of cells r/√2 across so that at most one point can ever occupy a cell. Then the question "is anything too close?" is 25 cells to look at, no matter whether you have placed ten points or ten thousand. Linear time, and it fits on a napkin. What sealed it was Yellott's 1983 result: the cones in the primate retina are laid out in exactly this kind of pattern — not a hexagonal grid, not independent randomness, but minimum-distance blue noise — which is why detail too fine for us to resolve arrives as a faint graininess instead of a confident, wrong pattern.
What I enjoy about it
The frontier. Nothing in the loop has a plan or a picture of the finished thing; there is only a to-do list of points that might still have elbow room, and a rule for taking yourself off it. A point retires the instant k darts in a row miss — which is a guess, not a proof. It might well have had space left. The algorithm doesn't check and doesn't care, and you can watch the consequence directly: set k to 3 and the pattern finishes early, pocked with holes it simply gave up on; set it to 30 and the identical code fills the plane. The outer edge of the ring is my other favourite detail. Two r looks arbitrary until you notice that anywhere further out is somebody else's job — if there is room over there, some other active point is nearer to it and will get there first. And then the pink. In uniform mode every point closer than r to a neighbour lights up, and at the default spacing that is more than four in five of them — the same number of points, dropped independently, and the picture is nearly all clump. Slow the speed right down to see the darts themselves, most of them bouncing off the crowded middle of the pattern while the edges are still wide open.
Something you might take away
"Random" and "evenly spread" are two different requests, and most of the time people asking for the first mean the second. Independence buys you fairness in expectation and clumps in practice — and the clumps have to be paid for, which is what the biggest-empty-circle readout is for: at the same number of points, uniform random leaves a hole roughly twice the radius of Poisson's. If you want a shuffle to feel fair, or a sensor layout not to alias, or a renderer's samples to miss nothing, the fix is not more randomness but a constraint against closeness. Spotify learned this in public — users were certain the shuffle was broken because the same artist kept coming up twice in a row, and the repair was to make it demonstrably less random. The other half of it is k. Retiring a point after a few misses is provably wrong and completely fine, and most fast algorithms have a dial like that somewhere: not a guarantee, just a budget for how long you're willing to keep asking before you decide the answer is no.