Skip to content

Instantly share code, notes, and snippets.

@aalin
Created June 6, 2013 10:55
Show Gist options
  • Save aalin/5720742 to your computer and use it in GitHub Desktop.
Save aalin/5720742 to your computer and use it in GitHub Desktop.
Catmull-Rom splines implemented in Ruby.
# Based on https://github.com/Sojo-Studios/catmull-rom/blob/master/test.js
# This implementation assumes circular splines.
class CatmullRomSplines
def initialize(points)
@key_points = points
end
def generate(detail)
points = []
@key_points.size.times do |i|
p0, p1, p2, p3 = adjacent_key_points(i)
detail.times do |d|
points << interpolate(d / detail.to_f, p0, p1, p2, p3)
end
end
points
end
private
def adjacent_key_points(index)
[
key_point(index - 1),
key_point(index),
key_point(index + 1),
key_point(index + 2)
]
end
def key_point(index)
@key_points[index % @key_points.size]
end
def interpolate(u, p0, p1, p2, p3)
u3 = u * u * u
u2 = u * u
f1 = -0.5 * u3 + u2 - 0.5 * u
f2 = 1.5 * u3 - 2.5 * u2 + 1.0
f3 = -1.5 * u3 + 2.0 * u2 + 0.5 * u
f4 = 0.5 * u3 - 0.5 * u2
# Handle arbitrary sizes
p0.zip(p1, p2, p3).map do |x0, x1, x2, x3|
x0 * f1 + x1 * f2 + x2 * f3 + x3 * f4
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment