kamelopard 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,7 @@
1
1
  #!env ruby
2
2
 
3
+ # :stopdoc:
4
+
3
5
  # The idea here is to ingest one tour from one KML document, and make it
4
6
  # multicamera-ish
5
7
 
@@ -2,9 +2,28 @@
2
2
  require 'bundler/setup'
3
3
  require 'matrix'
4
4
 
5
- # Basic support for splines
6
5
  module Kamelopard
7
6
  module Functions
7
+
8
+ # Provides basic support for Catmul-Rom splines, or in other words,
9
+ # calculating a nice smooth path through a series of "control points".
10
+ # You'll create a spline, add a bunch of control points, and then call
11
+ # run_function for a series of values between 0 and 1 to get the
12
+ # calculated points on the path.
13
+ #
14
+ # Mathematically, what this code calls a "point" is in fact a vector, a
15
+ # set of related numbers. Each number in the set represents one
16
+ # "dimension", the spline supports any number of dimensions, but each
17
+ # control point must have the same number. The returned vectors will
18
+ # also have that number of dimensions. Dimensions can represent
19
+ # whatever the user wants. For instance, the first might be "latitude",
20
+ # the second "longitude", and the third "altitude" (though common cases
21
+ # like that are already taken care of with SplineFunction descendants
22
+ # like PointSplineFunction and ViewSplineFunction).
23
+ #
24
+ # The tension value controls how tight the function's curves are. The
25
+ # usual resources (Google, Wikipedia, etc.) should provide sufficient
26
+ # discussion of Catmul-Rom splines to answer any detailed questions.
8
27
  class SplineFunction < FunctionMultiDim
9
28
  attr_reader :control_points, :total_dur, :tension
10
29
 
@@ -22,11 +41,18 @@ module Kamelopard
22
41
  # :dur are in whatever units the user wants; a spline with three
23
42
  # control points with durations of 0, 10, and 20 will be identical
24
43
  # to one with durations of 0, 1, and 2.
44
+ #--
45
+ # XXX: Raise an exception if the control point dimensionality
46
+ # doesn't match @ndims
47
+ #++
25
48
  def add_control_point(point, dur)
26
49
  @total_dur = @total_dur + dur if @control_points.size > 0
27
50
  @control_points << [ point, dur ]
28
51
  end
29
52
 
53
+ # Evaluates the spline function at a given value, which should be
54
+ # between 0 and 1. Returns an array of the same number of
55
+ # dimensions as each of the control points.
30
56
  def run_function(x)
31
57
  # X will be between 0 and 1
32
58
  # Find which control points I should am using for the point in
@@ -86,5 +112,77 @@ module Kamelopard
86
112
  return p.row(0)
87
113
  end
88
114
  end ## End of SplineFunction class
115
+
116
+ ## Spline that takes Points as control points
117
+ class PointSplineFunction < SplineFunction
118
+ def initialize(tension = 0.5)
119
+ @fields = [:longitude, :latitude, :altitude]
120
+ super(@fields.length, tension)
121
+ end
122
+
123
+ def add_control_point(point, dur)
124
+ super((
125
+ @fields.collect { |f|
126
+ begin
127
+ point.method(f).call
128
+ rescue
129
+ 0
130
+ end
131
+ }), dur)
132
+ end
133
+
134
+ def run_function(x)
135
+ res = super(x)
136
+ return point(h[0], h[1], h[2], @first_control_point.altitudeMode)
137
+ end
138
+ end
139
+
140
+ ## Spline that takes LookAts or Cameras as control points
141
+ class ViewSplineFunction < SplineFunction
142
+ attr_reader :viewtype, :first_control_point
143
+
144
+ def initialize(tension = 0.5)
145
+ @first_control_point = nil
146
+ @fields = [:latitude, :longitude, :altitude, :heading, :tilt, :roll, :range]
147
+ super(@fields.length, tension)
148
+ end
149
+
150
+ def add_control_point(point, dur)
151
+ raise "Control points for ViewSplines must be AbstractViews" unless point.kind_of? AbstractView
152
+ if @first_control_point.nil?
153
+ @first_control_point = point
154
+ elsif point.kind_of? @first_control_point.class
155
+ else
156
+ raise "Control points for ViewSplines must be the same class type (#{@first_control_point.class} vs #{point.class})"
157
+ end
158
+
159
+ super((
160
+ @fields.collect { |f|
161
+ begin
162
+ point.method(f).call
163
+ rescue
164
+ 0
165
+ end
166
+ }), dur)
167
+ end
168
+
169
+ def run_function(x)
170
+ res = super(x)
171
+ h = {}
172
+ @fields.each_index do |i|
173
+ h[@fields[i]] = res[i]
174
+ end
175
+
176
+ if @first_control_point.is_a? Kamelopard::LookAt
177
+ h.delete :roll
178
+ elsif @first_control_point.is_a? Kamelopard::Camera
179
+ h.delete :range
180
+ else
181
+ raise "Unknown control point type #{@first_control_point.class.name}. ViewSplines only support LookAts and Cameras"
182
+ end
183
+
184
+ return make_view_from h
185
+ end
186
+ end ## end of ViewSpline class
89
187
  end ## End of Function module
90
188
  end ## End of Kamelopard module