Wait, What?
Random points can be too random for graphics: they clump.
Poisson-disk sampling generates points that remain random-looking while enforcing a minimum separation. The result avoids both obvious lattice regularity and the heavy clumping of independent uniform random samples. Robert Bridson’s 2007 algorithm made this especially practical by using a background grid and an active list to generate Poisson-disk samples efficiently in arbitrary dimensions.
Quick Answer
Learn Bridson’s method through uniform randomness → minimum-distance constraint → blue-noise intuition → acceleration grid → active samples → annulus candidate generation → neighbourhood rejection → termination → complexity → dimension and boundary effects → production validation. The algorithm becomes simple once you understand why the grid makes minimum-distance tests local.
1. Why Independent Uniform Samples Clump
If points are sampled independently and uniformly, close pairs and empty gaps are normal statistical outcomes. That is correct randomness, but it can be visually undesirable for rendering, procedural placement, stippling, simulation seeding or spatial design. Poisson-disk sampling adds one strong geometric rule: no accepted pair may be closer than radius r.
The target is therefore not “maximum packing” and not a regular grid. It is a spatially well-spread random sample.
2. The Naive Algorithm Is Easy but Slow
A direct rejection sampler can repeatedly draw a random candidate and compare it with every accepted point. If it is at least r away from all of them, accept it. As the sample fills, acceptance becomes rarer and each candidate may require many distance checks. This is a good baseline because it makes the performance problem obvious.
3. Bridson’s Two Key Structures
- Background grid: stores accepted samples in cells sized so that only nearby cells can possibly contain a point closer than r.
- Active list: contains accepted points around which we still try to generate new candidates.
The grid removes the need to compare a candidate with every accepted sample. The active list grows the sample outward through local attempts rather than repeatedly throwing points across the entire domain.
4. Why the Grid Cell Size Matters
In d dimensions, a common Bridson construction uses grid cell side length approximately r/√d. The diagonal of such a cell is r, so two accepted samples cannot occupy the same cell if the minimum-distance rule is enforced. A candidate only needs to inspect a bounded neighbourhood of grid cells around its own cell.
This is the invariant that makes the algorithm fast: global geometric separation becomes a local lookup problem.
5. Generate Candidates in an Annulus
Choose an active point x. Generate up to k candidate points in the region whose distance from x lies between r and 2r. Candidates closer than r to x would certainly fail; candidates much farther away do not exploit the local frontier efficiently.
In two dimensions, sample a random direction and a radius in [r,2r], taking care that the radius distribution is appropriate for area rather than simply choosing radius uniformly if unbiased annulus area sampling matters. In higher dimensions, sample from the corresponding spherical shell or volume according to the intended variant.
6. Core Algorithm
choose one random initial sample
insert it into grid and active list
while active list is not empty:
choose an active sample x
accepted_new = false
repeat up to k times:
y = random candidate at distance in [r, 2r] from x
if y is inside domain and no nearby grid sample is within r:
accept y
insert y into grid
append y to active list
accepted_new = true
break
if no candidate was accepted:
remove x from active listBridson’s sketch commonly uses k=30 as a practical default, but k is an engineering parameter rather than a mathematical constant.
7. Trace a Small 2D Example
Use the unit square with r=0.2. Draw the acceleration grid. Place one initial sample and mark its cell. Generate several annulus candidates around it. For every candidate, inspect only the nearby grid cells that could contain a conflicting sample. When a candidate succeeds, add it to the active list. When an active sample fails k consecutive attempts, retire it.
This trace should make the frontier behaviour visible: the sample grows through neighbourhoods of already accepted points until no active point can find valid space nearby.
8. Complexity and the O(N) Claim
Bridson’s method is designed so that each candidate checks only a bounded number of nearby grid cells for fixed dimension and each active point receives only a bounded number k of candidate attempts before retirement. Under those assumptions, generating N samples has O(N)-style expected work in the algorithm’s intended setting.
Professional analysis should still count dimension, grid storage, boundary geometry and the chosen k. High-dimensional spaces are challenging because neighbourhood size and the volume of the domain grow rapidly.
9. Blue Noise Is a Distribution Property, Not Just a Distance Test
The minimum-distance rule prevents close pairs, but practitioners often care about the spectral and perceptual qualities associated with blue-noise sampling. Two methods can enforce similar minimum spacing while producing different higher-order structure. Therefore “Poisson disk” in production should be validated against the actual rendering, numerical-integration or placement requirement rather than by nearest-neighbour distance alone.
10. Current SciPy Behaviour Shows the Engineering Choices
Current SciPy documentation exposes scipy.stats.qmc.PoissonDisk and identifies the original Bridson algorithm as its volume-sampling strategy. It exposes the minimum radius, candidate count, dimensionality, bounds and random generator, and warns that the method is most suitable for relatively low dimensions because iterative sampling and memory demands become expensive as dimension grows.
SciPy also offers post-processing options, but its documentation explicitly warns that optimization after sampling may not preserve every original sample property. This is a useful professional boundary: post-processing can improve one quality metric while weakening another guarantee.
11. Boundary Conditions Change the Sample
A rectangular domain with hard boundaries naturally behaves differently near its edges because candidate neighbourhoods are truncated. If the application is tiling or texture synthesis, periodic boundary conditions may be more appropriate. Arbitrary polygons, surfaces and manifolds require domain-aware candidate generation and distance checks.
12. Determinism and Reproducibility
Poisson-disk sampling is stochastic. Production tests should fix a random seed or generator state when exact reproducibility matters. Even with the same parameters, different random seeds can produce different valid sample sets and different final counts.
13. Beginner → Professional Learning Progression
- Beginner: compare uniform random points with a minimum-distance sample visually.
- Foundation: implement the naive global rejection baseline.
- Intermediate: add the r/√d acceleration grid and local neighbour checks.
- Advanced: implement Bridson’s active-list annulus growth and analyse k, boundaries and density.
- Professional: validate nearest-neighbour statistics, spectral quality, runtime, reproducibility, high-dimensional behaviour and domain-specific boundary conditions.
14. Common Failure States
- Using grid cells that are too large and assuming one sample per cell is still safe.
- Checking too small a neighbourhood around the candidate.
- Generating candidates inside distance r of the active point.
- Removing an active point after one failed candidate instead of after its allotted attempts.
- Sampling radius incorrectly when uniform area/volume in the annulus is intended.
- Assuming the same k is optimal in every dimension and density regime.
- Calling a sample “blue noise” based only on visual impression.
15. How to Learn It Efficiently
Teach the performance transformation explicitly. First let learners implement or trace global rejection and count distance checks. Then give a worked grid example and ask which cells can possibly contain a violating neighbour. Only after that introduce the active list. Prediction, subgoal labels and faded Parsons-style code blocks help learners see the three jobs—generate locally, reject locally, retire exhausted seeds—before syntax dominates attention.
16. Learning Hall Boundary
This article owns Bridson-style minimum-distance Poisson-disk sampling and its active-list/grid acceleration. It does not replace generic random-number generation, quasi-Monte Carlo sampling, spatial indexing, collision detection or mesh-sampling owners.
Evidence Boundary and Further Reading
The canonical reference is Robert Bridson, “Fast Poisson Disk Sampling in Arbitrary Dimensions,” ACM SIGGRAPH 2007 Sketches. Current SciPy 1.18 documentation implements Poisson-disk sampling with parameters that expose the method’s practical trade-offs, including radius, candidate count and dimensionality.
- ACM Digital Library — Bridson 2007
- SciPy — current PoissonDisk documentation
- Geometry Central — Poisson-disk surface sampling
- ACM 2025 — Parsons problems and computing-education learning
Professional rule: you understand Bridson’s algorithm when you can prove why the acceleration grid makes the distance test local, explain the active-list frontier, and validate the resulting spatial distribution rather than judging it only by how attractive the dots look.
