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,45 @@
# utils/permutation
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The `permutation` module provides the seeded 512-byte permutation table plus the `fade` and `lerp` helpers used by every gradient-noise function in `@suaveplan/noise`. Centralising these shared utilities here keeps Perlin, Simplex, and Value noise consistent with one another: they all consume a table shuffled by `Sfc32Rng`.
## Features
- `buildPermutation(seed)` — seeded 512-byte Uint8Array; first 256 entries are a Fisher-Yates shuffle of `[0, 255]`, second 256 mirror the first (so hash wrap-around is free)
- `fade(t)` — Perlin's quintic fade curve `6t^5 - 15t^4 + 10t^3`
- `lerp(a, b, t)` — standard linear interpolation
## Usage: Basic Example
```ts
import { buildPermutation, fade } from "@suaveplan/noise";
const p = buildPermutation("terrain-42");
const f = fade(0.5); // 0.5
```
## Usage: Advanced Example
```ts
import { buildPermutation, fade, lerp } from "@suaveplan/noise";
const perm = buildPermutation(0);
// Hash 2D integer coordinates through the table:
function hash2(xi: number, yi: number): number {
return perm[((perm[xi & 0xff] as number) + (yi & 0xff)) & 0x1ff] as number;
}
```
## API Reference
- `buildPermutation(seed: string | number): Uint8Array` — deterministic 512-byte table.
- `fade(t: number): number` — Perlin's quintic smoothing, returns 0 at t=0 and 1 at t=1.
- `lerp(a: number, b: number, t: number): number` — returns `a + (b-a)*t`.
## Implementation Notes
Uint8Array uses one byte per entry, so the full table fits in 512 bytes of memory and stays in L1 cache during long noise evaluation loops. The Fisher-Yates shuffle runs 255 steps and uses `rng.nextUint32() % (i+1)` — the small modulo bias is statistically irrelevant for noise-table generation. The second-half mirror lets consumers do `perm[(a + b) & 0x1ff]` without branching or masking `a`/`b` first.