Class PoissonDiskSampler
A static utility class for generating uniformly distributed 2D points using Poisson disk sampling. Produces sets of points in which every pair of points is separated by at least a specified minimum distance, resulting in a natural, clump-free distribution that is visually superior to pure random placement.
Inherited Members
Namespace: Scylla.Core.Util.Random
Assembly: ScyllaCore.dll
Syntax
public static class PoissonDiskSampler
Remarks
Poisson disk sampling is ideal for procedural placement of game objects such as trees, rocks, enemies, collectibles, spawn points, and decorations, where uniform coverage without clustering or overlapping is desired.
This implementation uses Bridson's algorithm (Robert Bridson, "Fast Poisson Disk Sampling in
Arbitrary Dimensions", SIGGRAPH 2007). The algorithm maintains an active list of accepted points
and attempts to generate up to k candidate points in the annulus around each active
point. Each candidate is accepted if it satisfies the minimum distance constraint against all
nearby points, checked efficiently via a spatial hash grid. Time complexity is O(N) for N output
points.
Three entry points are available:
- SampleCircle(IRandomSource, Vector2, float, float, int) - samples within a circular region.
- SampleRectangle(IRandomSource, Vector2, Vector2, float, int) - samples within an axis-aligned rectangular region.
- Sample(IRandomSource, Vector2, BoundChecker, float, int) - samples within any custom region defined by a PoissonDiskSampler.BoundChecker delegate.
All methods accept any IRandomSource, enabling fully deterministic output when a seeded RNG is provided.
Methods
Sample(IRandomSource, Vector2, BoundChecker, float, int)
Generates a list of 2D points distributed within a custom region defined by a PoissonDiskSampler.BoundChecker delegate, using Poisson disk sampling. This is the core implementation used by SampleCircle(IRandomSource, Vector2, float, float, int) and SampleRectangle(IRandomSource, Vector2, Vector2, float, int). Use this overload when the sampling region is irregular, non-convex, or defined procedurally.
Declaration
public static List<Vector2> Sample(IRandomSource rng, Vector2 startPoint, PoissonDiskSampler.BoundChecker isInBounds, float minDistance, int k = 30)
Parameters
| Type | Name | Description |
|---|---|---|
| IRandomSource | rng | The random source used to drive candidate generation. Providing a seeded IRandomSource produces a deterministic, reproducible set of points. |
| Vector2 | startPoint | The initial accepted point that seeds the active list. This point is always the first element
of the returned list. It does not need to satisfy the |
| PoissonDiskSampler.BoundChecker | isInBounds | A PoissonDiskSampler.BoundChecker delegate invoked for each candidate point to determine whether
it falls within the desired sampling region. Must not be |
| float | minDistance | The minimum Euclidean distance that must be maintained between any two accepted points. Must be greater than 0. |
| int | k | The number of candidate points tried around each active point before that point is retired.
The default value of |
Returns
| Type | Description |
|---|---|
| List<Vector2> | A List<T> of UnityEngine.Vector2 points accepted by the algorithm.
All points satisfy the |
Remarks
The algorithm starts with startPoint (which must be within bounds, or it
will be the only point returned). It then iteratively selects an active point, generates
up to k candidate points in the annulus between
minDistance and 2 * minDistance from that point, and accepts candidates
that satisfy both the isInBounds check and the minimum distance
constraint against nearby accepted points. Active points that fail to produce a valid
candidate after k attempts are retired.
The spatial grid cell size is set to minDistance / sqrt(2) so that a 5x5 cell
neighbourhood search is sufficient to find all potentially conflicting accepted points.
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown if |
| ArgumentOutOfRangeException | Thrown if |
See Also
SampleCircle(IRandomSource, Vector2, float, float, int)
Generates a list of 2D points distributed within a circular region using Poisson disk sampling,
guaranteeing that no two points are closer than minDistance to each other.
Generation begins at the center of the circle.
Declaration
public static List<Vector2> SampleCircle(IRandomSource rng, Vector2 center, float radius, float minDistance, int k = 30)
Parameters
| Type | Name | Description |
|---|---|---|
| IRandomSource | rng | The random source used to drive candidate generation. Providing a seeded IRandomSource produces a deterministic, reproducible set of points. |
| Vector2 | center | The world-space center of the circular sampling region. |
| float | radius | The radius of the circular sampling region in world units. Must be greater than 0.
Points are included if their squared distance from |
| float | minDistance | The minimum Euclidean distance that must be maintained between any two accepted points. Smaller values produce denser point sets; larger values produce sparser sets. Must be greater than 0. |
| int | k | The number of candidate points tried around each active point before that point is retired
from the active list. Higher values fill the region more densely but require more iterations.
Defaults to |
Returns
| Type | Description |
|---|---|
| List<Vector2> | A List<T> of UnityEngine.Vector2 points, each within the specified circle
and separated from all others by at least |
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown if |
| ArgumentOutOfRangeException | Thrown if |
See Also
SampleRectangle(IRandomSource, Vector2, Vector2, float, int)
Generates a list of 2D points distributed within an axis-aligned rectangular region using
Poisson disk sampling, guaranteeing that no two points are closer than
minDistance to each other. Generation begins at the center of the rectangle.
Declaration
public static List<Vector2> SampleRectangle(IRandomSource rng, Vector2 center, Vector2 halfExtents, float minDistance, int k = 30)
Parameters
| Type | Name | Description |
|---|---|---|
| IRandomSource | rng | The random source used to drive candidate generation. Providing a seeded IRandomSource produces a deterministic, reproducible set of points. |
| Vector2 | center | The world-space center of the rectangular sampling region. |
| Vector2 | halfExtents | The half-width ( |
| float | minDistance | The minimum Euclidean distance that must be maintained between any two accepted points. Must be greater than 0. |
| int | k | The number of candidate points tried around each active point before that point is retired.
Defaults to |
Returns
| Type | Description |
|---|---|
| List<Vector2> | A List<T> of UnityEngine.Vector2 points, each within the specified rectangle
and separated from all others by at least |
Exceptions
| Type | Condition |
|---|---|
| ArgumentNullException | Thrown if |
| ArgumentOutOfRangeException | Thrown if either component of |