UNPKG

@thi.ng/math

Version:

Assorted common math functions & utilities

122 lines (121 loc) 3.9 kB
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 };