kamelopard 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/lib/kamelopard/classes.rb +69 -7
- data/lib/kamelopard/geocode.rb +57 -16
- data/lib/kamelopard/helpers.rb +834 -720
- data/lib/kamelopard/multicamify.rb +2 -0
- data/lib/kamelopard/spline.rb +99 -1
- data/spec/test.rb +2999 -0
- metadata +17 -15
data/lib/kamelopard/spline.rb
CHANGED
@@ -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
|