1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! Scalar linear, bilinear, and trilinear interpolation utilities.
//!
//! Mirrors culori 4.0.2's `interpolate/lerp.js`:
//!
//! ```js
//! const lerp = (a, b, t) => a + t * (b - a);
//! const unlerp = (a, b, v) => (v - a) / (b - a);
//!
//! const blerp = (a00, a01, a10, a11, tx, ty) =>
//! lerp(lerp(a00, a01, tx), lerp(a10, a11, tx), ty);
//!
//! const trilerp = (a000, a010, a100, a110, a001, a011, a101, a111,
//! tx, ty, tz) =>
//! lerp(blerp(a000, a010, a100, a110, tx, ty),
//! blerp(a001, a011, a101, a111, tx, ty),
//! tz);
//! ```
//!
//! Argument ordering for [`blerp`] and [`trilerp`] follows culori's positional
//! convention so per-bit reproduction across platforms holds.
/// 1-D linear interpolation: `a + t * (b - a)`.
/// Inverse of [`lerp`]: returns `t` such that `lerp(a, b, t) == value`.
///
/// When `a == b` the result is `NaN` (`(v - a) / 0`), matching culori.
/// Bilinear interpolation across a 2x2 grid.
///
/// Argument order matches culori's `blerp(a00, a01, a10, a11, tx, ty)`:
/// the first dimension (`tx`) lerps `a00→a01` and `a10→a11`; the second
/// (`ty`) lerps the two resulting values.
/// Trilinear interpolation across a 2x2x2 grid.
///
/// Argument order matches culori's `trilerp(a000, a010, a100, a110, a001,
/// a011, a101, a111, tx, ty, tz)`. The two `z`-slices are bilinearly
/// interpolated then lerped along `tz`.