[!NOTE] This is one of 190 standalone projects, maintained as part of the @thi.ng/umbrella monorepo and anti-framework.
🚀 Please help me to work full-time on these projects by sponsoring me on GitHub. Thank you! ❤️
nD Stratified grid and Poisson disc sampling with support for variable spatial density, custom PRNGs (via @thi.ng/random's IRandom
interface & implementations) and customizable quality settings.
The Poisson disc sampler requires a spatial index and we recommend using KdTreeSet
from the @thi.ng/geom-accel package to speed up the sampling process, but other ISpatialSet
-compatible indices are supported as well...
STABLE - used in production
Search or submit any issues for this package
yarn add @thi.ng/poisson
ES module import:
<script type="module" src="https://cdn.skypack.dev/@thi.ng/poisson"></script>
For Node.js REPL:
const poisson = await import("@thi.ng/poisson");
Package sizes (brotli'd, pre-treeshake): ESM: 757 bytes
Several projects in this repo's /examples directory are using this package:
Screenshot | Description | Live demo | Source |
---|---|---|---|
K-nearest neighbor search in an hash grid | Demo | Source | |
Poisson-disk shape-aware sampling, Voronoi & Minimum Spanning Tree visualization | Demo | Source | |
2D Poisson-disc sampler with procedural gradient map | Demo | Source | |
2D Stratified grid sampling example | Demo | Source |
The package provides a single function samplePoisson()
and the following options to customize the sampling process:
max
option) to avoid long delays.iter
param, increasing this value improves overall quality, especially in dense regions with small radii. Default: 500SYSTEM
(aka Math.random)import { asSvg, circle, svgDoc } from "@thi.ng/geom";
import { KdTreeSet } from "@thi.ng/geom-accel";
import { fit01 } from "@thi.ng/math";
import { samplePoisson } from "@thi.ng/poisson";
import { dist, randMinMax2 } from "@thi.ng/vectors";
const index = new KdTreeSet(2);
const pts = samplePoisson({
index,
points: () => randMinMax2(null, [0, 0], [500, 500]),
density: (p) => fit01(Math.pow(dist(p, [250, 250]) / 250, 2), 2, 10),
iter: 5,
max: 8000,
quality: 500,
});
// use thi.ng/geom to visualize results
// each circle's radius is set to distance to its nearest neighbor
const circles = pts.map((p) =>
circle(p, dist(p, index.queryKeys(p, 40, 2)[1]) / 2)
);
document.body.innerHTML = asSvg(
svgDoc({ fill: "none", stroke: "blue" }, ...circles)
);
The stratifiedGrid
function can produce 2D or 3D grid samples based on the following config options:
1/sqrt(2)
)SYSTEM
(aka Math.random)import { asSvg, group, line, points, svgDoc } from "@thi.ng/geom";
import { stratifiedGrid2 } from "@thi.ng/poisson";
import { map, range } from "@thi.ng/transducers";
const W = 50;
document.body.innerHTML = asSvg(
svgDoc(
{
width: 600,
height: 600,
fill: "blue",
stroke: "none",
},
// grid lines
group({ stroke: "#fcc", weight: 0.1 }, [
...map((x) => line([x, 0], [x, W]), range(1, W)),
...map((y) => line([0, y], [W, y]), range(1, W)),
]),
// grid samples as point cloud
points(
[...stratifiedGrid2({ dim: [W, W], separation: 0.5 })],
{ shape: "circle", size: 0.25 }
)
)
);
If this project contributes to an academic publication, please cite it as:
@misc{thing-poisson,
title = "@thi.ng/poisson",
author = "Karsten Schmidt",
note = "https://thi.ng/poisson",
year = 2016
}
© 2016 - 2024 Karsten Schmidt // Apache License 2.0
Generated using TypeDoc