there exist uniform, centripedal and chordal variants.
# evaluate a uniform Catmull-Rom spline segment at t in [0, 1]
catmull_rom = (p0, p1, p2, p3, t) ->
a0 = []
a1 = []
a2 = []
a3 = []
for i in [0...p1.length]
# cubic polynomial coefficients for each dimension
a0[i] = -0.5 * p0[i] + 1.5 * p1[i] - 1.5 * p2[i] + 0.5 * p3[i]
a1[i] = p0[i] - 2.5 * p1[i] + 2 * p2[i] - 0.5 * p3[i]
a2[i] = -0.5 * p0[i] + 0.5 * p2[i]
a3[i] = p1[i]
point = []
for i in [0...p1.length]
# evaluate cubic polynomial
point[i] = ((a0[i] * t + a1[i]) * t + a2[i]) * t + a3[i]
point
# generate interpolated path through given control points
catmull_rom_path = (points, resolution) ->
path = []
n = points.length
for i in [0...n - 1]
# duplicate endpoints as needed for interpolation at boundaries
p0 = if i is 0 then points[0] else points[i - 1]
p1 = points[i]
p2 = if i + 1 < n then points[i + 1] else points[n - 1]
p3 = if i + 2 < n then points[i + 2] else points[n - 1]
# sample points on spline segment from p1 to p2
for j in [0...resolution]
t = j / resolution
path.push catmull_rom p0, p1, p2, p3, t if i < n - 1 or j is 0
pathexample usage
example_points = [[-0.72, -0.3], [0, 0], [1, 0.8], [1.1, 0.5], [2.7, 1.2], [3.4, 0.27]]
path = catmull_rom_path example_points, 100
for p in path
console.log "#{p[0]} #{p[1]}"