@thi.ng/math
Version:
Assorted common math functions & utilities
122 lines (121 loc) • 3.9 kB
JavaScript
import { EPS, HALF_PI, PI } from "./api.js";
const mix = (a, b, t) => a + (b - a) * t;
const mixBilinear = (a, b, c, d, u, v) => {
const iu = 1 - u;
const iv = 1 - v;
return a * iu * iv + b * u * iv + c * iu * v + d * u * v;
};
const mixQuadratic = (a, b, c, t) => {
const s = 1 - t;
return a * s * s + b * 2 * s * t + c * t * t;
};
const mixCubic = (a, b, c, d, t) => {
const t2 = t * t;
const s = 1 - t;
const s2 = s * s;
return a * s2 * s + b * 3 * s2 * t + c * 3 * t2 * s + d * t2 * t;
};
const mixHermite = (a, b, c, d, t) => {
const y1 = 0.5 * (c - a);
const y2 = 1.5 * (b - c) + 0.5 * (d - a);
return ((y2 * t + a - b + y1 - y2) * t + y1) * t + b;
};
const mixCubicHermite = (a, ta, b, tb, t) => {
const s = t - 1;
const t2 = t * t;
const s2 = s * s;
const h00 = (1 + 2 * t) * s2;
const h10 = t * s2;
const h01 = t2 * (3 - 2 * t);
const h11 = t2 * s;
return h00 * a + h10 * ta + h01 * b + h11 * tb;
};
const mixCubicHermiteFromPoints = (a, b, c, d, t) => {
d *= 0.5;
const aa = -0.5 * a + 1.5 * b - 1.5 * c + d;
const bb = a - 2.5 * b + 2 * c - d;
const cc = -0.5 * a + 0.5 * c;
const dd = b;
const t2 = t * t;
return t * t2 * aa + t2 * bb + t * cc + dd;
};
const mixBicubic = (s00, s01, s02, s03, s10, s11, s12, s13, s20, s21, s22, s23, s30, s31, s32, s33, u, v) => mixCubicHermiteFromPoints(
mixCubicHermiteFromPoints(s00, s01, s02, s03, u),
mixCubicHermiteFromPoints(s10, s11, s12, s13, u),
mixCubicHermiteFromPoints(s20, s21, s22, s23, u),
mixCubicHermiteFromPoints(s30, s31, s32, s33, u),
v
);
const tangentCardinal = (prev, next, scale = 0.5, ta = 0, tc = 2) => scale * ((next - prev) / (tc - ta));
const tangentDiff3 = (prev, curr, next, ta = 0, tb = 1, tc = 2) => 0.5 * ((next - curr) / (tc - tb) + (curr - prev) / (tb - ta));
const tween = (f, from, to) => (t) => mix(from, to, f(t));
const circular = (t) => {
t = 1 - t;
return Math.sqrt(1 - t * t);
};
const invCircular = (t) => 1 - circular(1 - t);
const lens = (pos, strength, t) => {
const impl = strength > 0 ? invCircular : circular;
const tp = 1 - pos;
const tl = t <= pos ? impl(t / pos) * pos : 1 - impl((1 - t) / tp) * tp;
return mix(t, tl, Math.abs(strength));
};
const cosine = (t) => 1 - (Math.cos(t * PI) * 0.5 + 0.5);
const decimated = (n, t) => Math.floor(t * n) / n;
const bounce = (k, amp, t) => {
const tk = t * k;
return 1 - amp * Math.sin(tk) / tk * Math.cos(t * HALF_PI);
};
const ease = (ease2, t) => Math.pow(t, ease2);
const impulse = (k, t) => {
const h = k * t;
return h * Math.exp(1 - h);
};
const gain = (k, t) => t < 0.5 ? 0.5 * Math.pow(2 * t, k) : 1 - 0.5 * Math.pow(2 - 2 * t, k);
const parabola = (k, t) => Math.pow(4 * t * (1 - t), k);
const cubicPulse = (w, c, t) => {
t = Math.abs(t - c);
return t > w ? 0 : (t /= w, 1 - t * t * (3 - 2 * t));
};
const sinc = (t) => t !== 0 ? Math.sin(t) / t : 1;
const sincNormalized = (k, t) => sinc(PI * k * t);
const lanczos = (a, t) => t !== 0 ? -a < t && t < a ? sinc(PI * t) * sinc(PI * t / a) : 0 : 1;
const sigmoid = (bias, k, t) => t != bias ? 1 / (1 + Math.exp(-k * (t - bias))) : 0.5;
const sigmoid01 = (k, t) => sigmoid(0.5, k, t);
const sigmoid11 = (k, t) => sigmoid(0, k, t);
const schlick = (a, b, t) => t <= b ? b * t / (t + a * (b - t) + EPS) : (1 - b) * (t - 1) / (1 - t - a * (b - t) + EPS) + 1;
const expFactor = (a, b, num) => (b / a) ** (1 / num);
const gaussian = (bias, sigma, t) => Math.exp(-((t - bias) ** 2) / (2 * sigma * sigma));
export {
bounce,
circular,
cosine,
cubicPulse,
decimated,
ease,
expFactor,
gain,
gaussian,
impulse,
invCircular,
lanczos,
lens,
mix,
mixBicubic,
mixBilinear,
mixCubic,
mixCubicHermite,
mixCubicHermiteFromPoints,
mixHermite,
mixQuadratic,
parabola,
schlick,
sigmoid,
sigmoid01,
sigmoid11,
sinc,
sincNormalized,
tangentCardinal,
tangentDiff3,
tween
};