UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

90 lines (73 loc) 3.1 kB
import { catmull_rom_compute_T } from "./catmull_rom_compute_T.js"; /** * Computes derivative of Catmull Rom spline * @param {number[]} result_value * @param {number} result_value_offset * @param {number[]} result_derivative * @param {number} result_derivative_offset * @param {number[]} p0 spline point 0 * @param {number[]} p1 spline point 1 * @param {number[]} p2 spline point 2 * @param {number[]} p3 spline point 3 * @param {number} dimensions number of dimensions in the input and output vectors * @param {number} f between 0..1 * @param {number} alpha between 0..1 */ export function computeNonuniformCaltmullRomSplineDerivative( result_value, result_value_offset, result_derivative, result_derivative_offset, p0, p1, p2, p3, dimensions, f, alpha ) { /* @see https://math.stackexchange.com/questions/843595/how-can-i-calculate-the-derivative-of-a-catmull-rom-spline-with-nonuniform-param @see http://denkovacs.com/2016/02/catmull-rom-spline-derivatives/ @see https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline */ const half_alpha = alpha * 0.5; // calculate T const t0 = 0; let t_01 = catmull_rom_compute_T(p0, p1, dimensions, half_alpha); let t_02 = catmull_rom_compute_T(p1, p2, dimensions, half_alpha); let t_03 = catmull_rom_compute_T(p2, p3, dimensions, half_alpha); // safety check for repeated points, to prevent division by 0 if (t_01 < 1e-4) { t_01 = 1; } if (t_02 < 1e-4) { t_02 = t_01; } if (t_03 < 1e-4) { t_03 = t_02; } const t1 = t_01 + t0; const t2 = t_02 + t1; const t3 = t_03 + t2; /** * Interpolation between points 1 and 2 * @type {number} */ const t = t1 * (1 - f) + t2 * f; for (let i = 0; i < dimensions; i++) { // read vector values for the dimension const v0 = p0[i]; const v1 = p1[i]; const v2 = p2[i]; const v3 = p3[i]; const A1 = (t1 - t) / (t1 - t0) * v0 + (t - t0) / (t1 - t0) * v1; const A2 = (t2 - t) / (t2 - t1) * v1 + (t - t1) / (t2 - t1) * v2; const A3 = (t3 - t) / (t3 - t2) * v2 + (t - t2) / (t3 - t2) * v3; const B1 = (t2 - t) / (t2 - t0) * A1 + (t - t0) / (t2 - t0) * A2; const B2 = (t3 - t) / (t3 - t1) * A2 + (t - t1) / (t3 - t1) * A3; const C = (t2 - t) / (t2 - t1) * B1 + (t - t1) / (t2 - t1) * B2; result_value[result_value_offset + i] = C; // derivatives const dA1 = (v1 - v0) / (t1 - t0) const dA2 = (v2 - v1) / (t2 - t1); const dA3 = (v3 - v2) / (t3 - t2); const dB1 = (A2 - A1) / (t2 - t0) + dA1 * (t2 - t) / (t2 - t0) + dA2 * (t - t0) / (t2 - t0); const dB2 = (A3 - A2) / (t3 - t1) + dA2 * (t3 - t) / (t3 - t1) + dA3 * (t - t1) / (t3 - t1); const dC = (B2 - B1) / (t2 - t1) + dB1 * (t2 - t) / (t2 - t1) + dB2 * (t - t1) / (t2 - t1); result_derivative[result_derivative_offset + i] = dC; } }