Crate fast_poisson[−][src]
Generate a Poisson disk distribution.
This is an implementation of Bridson’s “Fast Poisson Disk Sampling” algorithm in arbitrary dimensions.
- Iterator-based generation lets you leverage the full power of Rust’s Iterators
- Lazy evaluation of the distribution means that even complex Iterator chains are as fast as O(N); with other libraries operations like mapping into another struct become O(N²) or more!
- Using Rust’s const generics allows you to consume the distribution with no additional dependencies
Features
These are the optional features you can enable in your Cargo.toml:
single_precision
changes the output, and all of the internal calculations, from using double-precisionf64
to single-precisionf32
. Distributions generated with thesingle-precision
feature are not required nor expected to match those generated without it.small_rng
changes the internal PRNG used to generate the distribution: By defaultXoshiro256StarStar
is used, but with this feature enabled thenXoshiro128StarStar
is used instead. This reduces the memory used for the PRNG’s state from 256 bits to 128 bits, and may be more performant for 32-bit systems.derive_serde
automatically derives Serde’s Serialize and Deserialize traits forPoisson
, This relies on theserde_arrays
crate to allow (de)serializing the const generic arrays used byPoisson
.
Requirements
This library requires Rust 1.51.0 or later, as it relies on const generics to return fixed-length points (e.g. [x, y] or [x, y, z]) without adding additional external dependencies to your code.
Examples
use fast_poisson::Poisson2D; // Easily generate a simple `Vec` let points: Vec<[f64; 2]> = Poisson2D::new().generate(); // To fill a box, specify the width and height: let points = Poisson2D::new().with_dimensions([100.0, 100.0], 5.0); // Leverage `Iterator::map` to quickly and easily convert into a custom type in O(N) time! // Also see the `Poisson::to_vec()` method struct Point { x: f64, y: f64, } let points = Poisson2D::new().iter().map(|[x, y]| Point { x, y }); // Distributions are lazily evaluated; here only 5 points will be calculated! let points = Poisson2D::new().iter().take(5); // `Poisson` can be directly consumed in for loops: for point in Poisson2D::new() { println!("X: {}; Y: {}", point[0], point[1]); }
Higher-order Poisson disk distributions are generated just as easily:
use fast_poisson::{Poisson, Poisson3D, Poisson4D}; // 3-dimensional distribution let points_3d = Poisson3D::new().iter(); // 4-dimensional distribution let mut points_4d = Poisson4D::new(); // To achieve desired levels of performance, you should set a larger radius for higher-order // distributions points_4d.with_dimensions([1.0; 4], 0.2); let points_4d = points_4d.iter(); // For more than 4 dimensions, use `Poisson` directly: let mut points_7d = Poisson::<7>::new(); points_7d.with_dimensions([1.0; 7], 0.6); let points_7d = points_7d.iter();
Upgrading
0.4.x
This version is 100% backwards-compatible with 0.3.x and 0.2.0, however fast_poisson
has been
relicensed as of this version.
Several bugs were identified and fixed in the underlying algorithms; as a result, distributions generated with 0.4.0 will not match those generated in earlier versions.
0.3.x
This version adds no breaking changes and is backwards-compatible with 0.2.0.
0.2.0
This version adds some breaking changes:
2 dimensions no longer assumed
In version 0.1.0 you could directly instantiate Poisson
and get a 2-dimensional distribution.
Now you must specifiy that you want 2 dimensions using either Poisson<2>
or Poisson2D
.
Returned points are arrays
In version 0.1.0 the distribution was returned as an iterator over (f64, f64)
tuples
representing each point. To leverage Rust’s new const generics feature and support arbitrary
dimensions, the N-dimensional points are now [f64; N]
arrays.
Builder pattern
Use the build pattern to instantiate new distributions. This will not work:
let poisson = Poisson2D { width: 100.0, height: 100.0, radius: 5.0, ..Default::default() }; let points = poisson.iter();
Instead, leverage the new builder methods:
let mut poisson = Poisson2D::new(); poisson.with_dimensions([100.0; 2], 5.0); let points = poisson.iter();
This change frees me to make additional changes to how internal state is stored without necessarily requiring additional changes to the API.
Structs
Iter | An iterator over the points in the Poisson disk distribution |
Poisson | Poisson disk distribution in N dimensions |
Type Definitions
Point | A Point is simply an array of Float values |
Poisson2D |
|
Poisson3D |
|
Poisson4D |
|