first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
# blue/blue
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The `blue` module implements Robert Bridson's fast Poisson-disk sampling algorithm to generate an approximately blue-noise distribution of points in a 2D rectangle. Blue noise's defining property is that every pair of samples is at least `radius` apart, while their positions appear random — it is the gold standard for anti-aliased dithering, stippling, foliage placement, and any sampling application where regular grids produce visible artefacts.
## Features
- `blueNoiseSample({ width, height, radius, k?, maxSamples?, seed? })`
- Seeded with `Sfc32Rng` for reproducible output
- Bridson's spatial grid for O(n) amortised point insertion
- `maxSamples` guard converts runaway parameters into a typed `NoiseError` instead of an out-of-memory crash
## Usage: Basic Example
```ts
import { blueNoiseSample } from "@suaveplan/noise";
const dots = blueNoiseSample({ width: 400, height: 300, radius: 10, seed: 42 });
```
## Usage: Advanced Example
```ts
import { blueNoiseSample } from "@suaveplan/noise";
const trees = blueNoiseSample({
width: 2048,
height: 2048,
radius: 32, // minimum canopy spacing
k: 50, // higher k = denser packing
maxSamples: 20_000,
seed: "forest-2026-04-19",
});
for (const [x, y] of trees) plantTree(x, y);
```
## API Reference
- `BlueNoiseOptions`:
- `width`, `height`: rectangle size (must be positive finite)
- `radius`: minimum spacing between samples (positive finite)
- `k`: candidate neighbours per active sample (default 30)
- `maxSamples`: hard ceiling (default 100 000) — throws `NoiseError.BLUE.MAX_SAMPLES_EXCEEDED` if exceeded
- `seed`: `string | number` passed through to `Sfc32Rng` (default 0)
- `blueNoiseSample(opts): Array<[number, number]>`
## Implementation Notes
A spatial background grid with `cellSize = radius / √2` guarantees at most one sample per cell, so the neighbour check only has to scan a 5×5 window (the 2-cell radius is the Bridson-recommended value). The `maxSamples` guard protects against the common user error of specifying a tiny radius relative to the rectangle — without it, `O(area/radius²)` can explode. `k` above 30 gives denser packing but longer runtimes; 30 is the paper's recommended value.