mx / src /video /math.ts
Ethscriptions's picture
Step 3-4: 3D 解剖模型与分镜时间轴
213d393 verified
Raw History Blame Contribute Delete
2.15 kB
export type V3 = [number, number, number]
export const clamp = (x: number, a = 0, b = 1) => Math.min(b, Math.max(a, x))
export const lerp = (a: number, b: number, t: number) => a + (b - a) * t
export const smooth = (t: number) => { t = clamp(t); return t * t * (3 - 2 * t) }
export const smoother = (t: number) => { t = clamp(t); return t * t * t * (t * (t * 6 - 15) + 10) }
export const easeOut = (t: number) => 1 - Math.pow(1 - clamp(t), 3)
export const easeIn = (t: number) => Math.pow(clamp(t), 3)
export const easeInOut = (t: number) => smoother(t)
export const backOut = (t: number) => { t = clamp(t); const c1 = 1.70158, c3 = c1 + 1; return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2) }
/** 0→1 ramp between a and b */
export const ramp = (x: number, a: number, b: number) => clamp((x - a) / (b - a))
/** fade in over [a,a+fi], hold, fade out over [b-fo,b] */
export const win = (x: number, a: number, b: number, fi = 0.3, fo = 0.3) =>
Math.min(smooth(ramp(x, a, a + fi)), 1 - smooth(ramp(x, b - fo, b)))
export const lerpV = (a: V3, b: V3, t: number): V3 => [lerp(a[0], b[0], t), lerp(a[1], b[1], t), lerp(a[2], b[2], t)]
export const lerpArr = (a: number[], b: number[], t: number) => a.map((v, i) => lerp(v, b[i], t))
/** Keyframe interpolation for numbers / arrays. keys: [time, value] sorted. */
export function kf<T extends number | number[]>(x: number, keys: [number, T][], ease: (t: number) => number = smoother): T {
if (x <= keys[0][0]) return keys[0][1]
for (let i = 0; i < keys.length - 1; i++) {
const [t0, v0] = keys[i], [t1, v1] = keys[i + 1]
if (x <= t1) {
const k = ease((x - t0) / Math.max(1e-6, t1 - t0))
if (typeof v0 === 'number') return lerp(v0, v1 as number, k) as T
return lerpArr(v0 as number[], v1 as number[], k) as T
}
}
return keys[keys.length - 1][1]
}
/** deterministic hash noise */
export const hash = (n: number) => { const s = Math.sin(n * 127.1 + 311.7) * 43758.5453; return s - Math.floor(s) }
export const noise1 = (x: number) => { const i = Math.floor(x), f = x - i; const u = f * f * (3 - 2 * f); return lerp(hash(i), hash(i + 1), u) * 2 - 1 }