UNPKG

cat-rom-spline-generic

Version:

Catmull Rom spline interpolation made easy.

82 lines (64 loc) 2.13 kB
function add(out, a, b) { out[0] = a[0] + b[0] out[1] = a[1] + b[1] return out } function scale(out, a, b) { out[0] = a[0] * b out[1] = a[1] * b return out } function distance(a, b) { var x = b[0] - a[0], y = b[1] - a[1] return Math.sqrt(x*x + y*y) } var interpolatePoint = function(p0, p1, p2, p3, t0, t1, t2, t3, t) { var a1, a2, a3, b1, b2, c; a1 = []; a2 = []; a3 = []; b1 = []; b2 = []; c = []; add(a1, scale([], p0, (t1 - t)/(t1 - t0)), scale([], p1, (t - t0)/(t1 - t0))); add(a2, scale([], p1, (t2 - t)/(t2 - t1)), scale([], p2, (t - t1)/(t2 - t1))); add(a3, scale([], p2, (t3 - t)/(t3 - t2)), scale([], p3, (t - t2)/(t3 - t2))); add(b1, scale([], a1, (t2 - t)/(t2 - t0)), scale([], a2, (t - t0)/(t2 - t0))); add(b2, scale([], a2, (t3 - t)/(t3 - t1)), scale([], a3, (t - t1)/(t3 - t1))); add(c, scale([], b1, (t2 - t)/(t2 - t1)), scale([], b2, (t - t1)/(t2 - t1))); return c; }; var catmullSegmentAtTime = function(p0, p1, p2, p3, t, knot) { var ft, t0, t1, t2, t3, segmentDist; var points = []; segmentDist = distance(p1, p2); t0 = 0; t1 = Math.pow(distance(p0, p1), knot); t2 = Math.pow(segmentDist, knot) + t1; t3 = Math.pow(distance(p2, p3), knot) + t2; ft = t1+(t*(t2 - t1)); return interpolatePoint(p0, p1, p2, p3, t0, t1, t2, t3, ft); }; var catmullRomSpline = function(controlPoints, options) { if (controlPoints.length < 4) { throw "Must have at least 4 control points to generate catmull rom spline"; } var points = []; var p0, p1, p2, p3, offset; options = options || {}; var knot = options.knot || 0.5; var samples = options.samples; var pointsPerSegment = samples/(controlPoints.length-3); for(var i = 0; i < samples; ++i){ var pos = Math.floor(i/pointsPerSegment); var p0 = controlPoints[pos]; var p1 = controlPoints[pos+1]; var p2 = controlPoints[pos+2]; var p3 = controlPoints[pos+3]; var t = i/pointsPerSegment - Math.floor(i/pointsPerSegment); points.push(catmullSegmentAtTime(p0, p1, p2, p3, t, knot)); } return points; }; export {catmullRomSpline};