kamelopard 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -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