This isn't the same story as the plain quadtree query demos on this site — those measure how many nodes get visited answering a query. This one measures how many bytes the structure itself occupies, which is the actual meaning of "spatial compression": representing where the data is without paying for the empty space around it.
Every quadtree node here costs a fixed number of bytes, and every stored point costs a fixed number of bytes:
BYTES_PER_NODE = 44 (4 child pointers × 8B + cx,cy,half as 3 float32 × 4B)
BYTES_PER_POINT = 8 (x, y as two float32)
treeBytes = totalNodes × 44 + totalPoints × 8
The comparison is a naive dense grid covering the whole domain at the same finest resolution the quadtree actually reached this run (2^depth cells per side) — the resolution you would need with a flat array to tell points apart as precisely as the tree does at its deepest leaf:
gridSide = 2^depthReached
gridCells = gridSide²
gridBytes = gridCells × BYTES_PER_CELL (selectable above, 1 byte by default)
ratio = gridBytes / treeBytes
The honest part: for uniformly scattered points the tree rarely needs to subdivide deep, so the matching dense grid stays small too — the ratio can sit close to 1× or even favour the grid slightly. Drag the Clustering slider up: points start piling into a few tight clusters, forcing deep local subdivision, and the dense grid — which must apply that fine resolution to the entire domain, not just the crowded corner — balloons while the tree's byte cost barely moves. That gap, not query speed, is what "spatial compression" actually buys you: a sparse structure that only pays for the regions that hold data.
- Point count / Clustering — regenerate the point set; clustering blends uniform placement with a handful of tight Gaussian blobs.
- Capacity per leaf / Max depth — the same subdivision rules as any PR quadtree; a lower capacity or higher depth cap lets the tree (and therefore the matching grid) go deeper.
- Dense-grid cost per cell — even at the most generous 1-bit-per-cell bitmap, a sufficiently clustered point set still makes the fixed-resolution grid lose, because it can't skip empty regions the way the tree does.