Class: Kamelopard::Functions::SplineFunction
- Inherits:
-
FunctionMultiDim
- Object
- Function
- FunctionMultiDim
- Kamelopard::Functions::SplineFunction
- Defined in:
- lib/kamelopard/spline.rb
Instance Attribute Summary collapse
-
#control_points ⇒ Object
readonly
Returns the value of attribute control_points.
-
#tension ⇒ Object
readonly
Returns the value of attribute tension.
-
#total_dur ⇒ Object
readonly
Returns the value of attribute total_dur.
Attributes inherited from FunctionMultiDim
Attributes inherited from Function
#append, #compose, #end, #max, #min, #start, #verbose
Instance Method Summary collapse
-
#add_control_point(point, dur) ⇒ Object
Adds a new control point.
-
#initialize(ndims, tension = 0.5) ⇒ SplineFunction
constructor
A new instance of SplineFunction.
- #run_function(x) ⇒ Object
Methods inherited from FunctionMultiDim
Methods inherited from Function
Constructor Details
#initialize(ndims, tension = 0.5) ⇒ SplineFunction
Returns a new instance of SplineFunction.
10 11 12 13 14 15 16 |
# File 'lib/kamelopard/spline.rb', line 10 def initialize(ndims, tension = 0.5) @ndims = ndims @control_points = [] @total_dur = 0 @tension = tension super() end |
Instance Attribute Details
#control_points ⇒ Object (readonly)
Returns the value of attribute control_points.
8 9 10 |
# File 'lib/kamelopard/spline.rb', line 8 def control_points @control_points end |
#tension ⇒ Object (readonly)
Returns the value of attribute tension.
8 9 10 |
# File 'lib/kamelopard/spline.rb', line 8 def tension @tension end |
#total_dur ⇒ Object (readonly)
Returns the value of attribute total_dur.
8 9 10 |
# File 'lib/kamelopard/spline.rb', line 8 def total_dur @total_dur end |
Instance Method Details
#add_control_point(point, dur) ⇒ Object
Adds a new control point. :dur is a way of indicating the duration of the journey from the last point to this one, and is ignored for the first control point in the spline. Values for :dur are in whatever units the user wants; a spline with three control points with durations of 0, 10, and 20 will be identical to one with durations of 0, 1, and 2.
24 25 26 27 |
# File 'lib/kamelopard/spline.rb', line 24 def add_control_point(point, dur) @total_dur = @total_dur + dur if @control_points.size > 0 @control_points << [ point, dur ] end |
#run_function(x) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/kamelopard/spline.rb', line 29 def run_function(x) # X will be between 0 and 1 # Find which control points I should am using for the point in # question dur = 0 last_dur = 0 cur_i = 0 u = 0 @control_points.each_index do |i| next if i == 0 cur_i = i last_dur = dur if 1.0 * (dur + @control_points[i][1]) / @total_dur >= x then # I've found the correct two control points: cp[i-1] and cp[i] # u is the point on the interval between the two control points # that we're interested in. 0 would be the first control point, # and 1 the second u = (x * @total_dur - dur) / @control_points[i][1] break end dur = dur + @control_points[i][1] end # http://www.cs.cmu.edu/~462/projects/assn2/assn2/catmullRom.pdf # cp = control points. cur_i will be at least 1 # I need two control points on either side of this part of the # spline. If they don't exist, duplicate the endpoints of the # control points. cp1 = @control_points[cur_i-1][0] cp2 = @control_points[cur_i][0] if cur_i == 1 then cpt1 = cp1 else cpt1 = @control_points[cur_i-2][0] end if cur_i >= @control_points.size - 1 then cpt2 = cp2 else cpt2 = @control_points[cur_i+1][0] end # Can't just say Matrix[cp], because that adds an extra # dimension to the matrix, somehow. cps = Matrix[cpt1, cp1, cp2, cpt2] t = @tension h = Matrix[ [ 0, 1, 0, 0 ], [ -t, 0, t, 0 ], [ 2*t, t-3, 3-2*t, -t ], [ -t, 2-t, t-2, t] ] p = Matrix[[1, u, u**2, u**3]] * h * cps return p end |