Files
skills/docs/foundation/random/noise/src/blue/blue.md
2026-05-29 08:20:56 +01:00

2.3 KiB
Raw Blame History

blue/blue

(no submodules)

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

import { blueNoiseSample } from "@suaveplan/noise";

const dots = blueNoiseSample({ width: 400, height: 300, radius: 10, seed: 42 });

Usage: Advanced Example

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.