Crate fast_poisson[][src]

Generate a Poisson disk distribution.

This is an implementation of Bridson’s “Fast Poisson Disk Sampling” algorithm in arbitrary dimensions.

Features

  • 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 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

Examples

To generate a simple Poisson disk pattern in the range (0, 1] for each of the x and y dimensions:

use fast_poisson::Poisson2D;

let points = Poisson2D::new().iter();

To fill a box, specify the width and height:

use fast_poisson::Poisson2D;

let points = Poisson2D::new().with_dimensions([100.0, 100.0], 5.0).iter();

Because iter returns an iterator, you have access to the full power of Rust iterator methods to further manipulate the results, and all within O(N) time because the distribution is lazily generated within each iteration:

use fast_poisson::Poisson2D;

struct Point {
    x: f64,
    y: f64,
}

// Map the Poisson disk points to our `Point` struct in O(N) time!
let points = Poisson2D::new().iter().map(|[x, y]| Point { x, y });

You can even take just a subset of the distribution without ever spending time calculating the discarded points:

use fast_poisson::Poisson2D;

// Only 5 points from the distribution are actually generated!
let points = Poisson2D::new().iter().take(5);

Poisson implements IntoIterator, so you can e.g. directly consume it with a for loop:

use fast_poisson::Poisson2D;

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.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

Poisson

Poisson disk distribution in N dimensions

PoissonIter

An iterator over the points in the Poisson disk distribution

Type Definitions

Poisson2D

Poisson disk distribution in 2 dimensions

Poisson3D

Poisson disk distribution in 3 dimensions

Poisson4D

Poisson disk distribution in 4 dimensions