18[[nodiscard]]
constexpr T
map(T x, T in_lo, T in_hi, T out_lo, T out_hi)
noexcept
20 const T in_range = in_hi - in_lo;
21 if (in_range == T { 0 })
23 return out_lo + (x - in_lo) / in_range * (out_hi - out_lo);
31[[nodiscard]]
constexpr T
map_clamped(T x, T in_lo, T in_hi, T out_lo, T out_hi)
noexcept
33 const T v =
map(x, in_lo, in_hi, out_lo, out_hi);
34 return std::clamp(v, std::min(out_lo, out_hi), std::max(out_lo, out_hi));
46[[nodiscard]]
constexpr T
normalize(T x, T lo, T hi)
noexcept
48 const T range = hi - lo;
51 return (x - lo) / range;
61[[nodiscard]]
constexpr T
denormalize(T t, T lo, T hi)
noexcept
63 return lo + t * (hi - lo);
80[[nodiscard]]
constexpr T
smoothstep(T lo, T hi, T x)
noexcept
82 const T t = std::clamp((x - lo) / (hi - lo), T { 0 }, T { 1 });
83 return t * t * (T { 3 } - T { 2 } * t);
96 const T t = std::clamp((x - lo) / (hi - lo), T { 0 }, T { 1 });
97 return t * t * t * (t * (t * T { 6 } - T { 15 }) + T { 10 });
115[[nodiscard]]
inline T
damp(T
current, T target, T smoothing, T dt)
noexcept
117 if (smoothing <= T { 0 })
119 return current + (target -
current) * (T { 1 } - std::exp(-dt / smoothing));
135[[nodiscard]]
inline T
wrap(T x, T lo, T hi)
noexcept
137 const T range = hi - lo;
138 if (range <= T { 0 })
140 return x - range * std::floor((x - lo) / range);
153[[nodiscard]]
inline T
ping_pong(T x, T lo, T hi)
noexcept
155 const T range = hi - lo;
156 if (range <= T { 0 })
158 const T shifted = x - lo;
159 const T period = T { 2 } * range;
160 const T t = shifted - period * std::floor(shifted / period);
161 return lo + (t < range ? t : period - t);
176[[nodiscard]]
inline T
snap(T x, T step)
noexcept
180 return std::round(x / step) * step;
187[[nodiscard]]
inline T
snap(T x, T lo, T hi, T step)
noexcept
189 return std::clamp(
snap(x, step), lo, hi);
201[[nodiscard]]
constexpr T
ease_in(T t)
noexcept
213 const T u = T { 1 } - t;
214 return T { 1 } - u * u * u;
225 ? T { 4 } * t * t * t
226 : T { 1 } - T { 4 } * (T { 1 } - t) * (T { 1 } - t) * (T { 1 } - t) * T { 0.5 };
248 const T sign = x > T { 0 } ? T { 1 } : T { -1 };
261 return x < T { 0 } ? T { -1 } : T { 1 };
T ping_pong(T x, T lo, T hi) noexcept
Ping-pong (triangle wave): fold x back and forth in [lo, hi].
T damp(T current, T target, T smoothing, T dt) noexcept
Exponential smoothing: move current toward target at rate smoothing over time step dt.
constexpr T denormalize(T t, T lo, T hi) noexcept
Denormalize t from [0, 1] to [lo, hi].
constexpr T normalize(T x, T lo, T hi) noexcept
Normalize x in [lo, hi] to [0, 1], unclamped.
T snap(T x, T step) noexcept
Round x to the nearest multiple of step.
constexpr T ease_in(T t) noexcept
Cubic ease-in: slow start, fast end.
constexpr T smootherstep(T lo, T hi, T x) noexcept
Ken Perlin's quintic smootherstep: C2-continuous in [lo, hi].
Tendency< D, float > threshold(const Tendency< D, float > &t, float thresh)
Zero output below threshold, pass through above.
constexpr T ease_in_out(T t) noexcept
Cubic ease-in-out: slow start, fast middle, slow end.
constexpr T map(T x, T in_lo, T in_hi, T out_lo, T out_hi) noexcept
Map x from [in_lo, in_hi] to [out_lo, out_hi], unclamped.
constexpr T ease_out(T t) noexcept
Cubic ease-out: fast start, slow end.
constexpr T map_clamped(T x, T in_lo, T in_hi, T out_lo, T out_hi) noexcept
Map x from [in_lo, in_hi] to [out_lo, out_hi], clamped to [out_lo, out_hi].
constexpr T smoothstep(T lo, T hi, T x) noexcept
GLSL smoothstep: Hermite interpolation in [lo, hi].
T wrap(T x, T lo, T hi) noexcept
Wrap x into [lo, hi) with modulo semantics.
constexpr T sign_nonzero(T x) noexcept
Sign of x, returning -1 or +1, never 0.
constexpr T deadzone(T x, T threshold) noexcept
Zero values within [-threshold, threshold] and rescale the remainder to fill [0, 1] (or [-1,...