interpolate 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ == 0.2.0
2
+
3
+ * Changed the library name to "interpolate"
4
+ * Added Array#interpolate that covers uniform arrays and nested arrays
5
+ * Added more tests, documentation, and examples
6
+
7
+ == 0.1.0
8
+
9
+ * Gadient calls :interpolate on values for OOP goodness
10
+ * Checks added for respond_to? :interpolate on values
11
+ * Added Numeric#interpolate
12
+
13
+ == 0.0.1
14
+
15
+ * Initial coding
16
+ * N-sized arbitrary floating point gradients
17
+
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Adam Collins [adam.w.collins@gmail.com]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,11 @@
1
+ CHANGELOG
2
+ MIT-LICENSE
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ examples/arrays.rb
7
+ examples/colors.rb
8
+ examples/nested.rb
9
+ examples/zones.rb
10
+ lib/interpolate.rb
11
+ test/test_all.rb
@@ -0,0 +1,11 @@
1
+ == Interpolate
2
+
3
+ Library for generic interpolation objects. Useful for such things as generating
4
+ linear motion between points (or arrays of points), multi-channel color
5
+ gradients, piecewise functions, or even just placing values within intervals.
6
+
7
+ == Author
8
+
9
+ Adam Collins
10
+ adam.w.collins@gmail.com
11
+
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'hoe'
3
+ $:.unshift(File.dirname(__FILE__) + "/lib")
4
+ require 'interpolate'
5
+
6
+ Hoe.new('Interpolate', Interpolation::VERSION) do |p|
7
+ p.name = "interpolate"
8
+ p.author = "Adam Collins"
9
+ p.description = "Library for creating generic interpolations objects."
10
+ p.email = 'adam.w.collins@gmail.com'
11
+ p.summary = "Useful for such things as generating linear motion between points (or arrays of points), multi-channel color gradients, piecewise functions, or even just placing values within intervals."
12
+ p.url = "http://interpolate.rubyforge.org"
13
+ #p.clean_globs = [''] # Remove this directory on "rake clean"
14
+ p.remote_rdoc_dir = '' # Release to root
15
+ p.changes = p.paragraphs_of('CHANGELOG', 0..1).join("\n\n")
16
+ # * extra_deps - An array of rubygem dependencies.
17
+ end
18
+
19
+ desc "Release and publish documentation"
20
+ task :repubdoc => [:release, :publish_docs]
21
+
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'interpolate'
3
+ require 'pp'
4
+
5
+
6
+ # a non-linear set of multi-dimensional points;
7
+ # perhaps the location of some actor in relation to time
8
+ time_frames = {
9
+ 0 => [0, 0, 0],
10
+ 1 => [1, 0, 0],
11
+ 2 => [0, 1, 0],
12
+ 3 => [0, 0, 2],
13
+ 4 => [3, 0, 1],
14
+ 5 => [1, 2, 3],
15
+ 6 => [0, 0, 0]
16
+ }
17
+
18
+ path = Interpolation.new(time_frames)
19
+
20
+ # play the actors positions in time increments of 0.25
21
+ (0).step(6, 0.25) do |time|
22
+ position = path.at(time)
23
+ puts ">> At #{time}s, actor is at:"
24
+ p position
25
+ end
26
+
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'interpolate'
3
+ require 'color'
4
+
5
+
6
+ # we need to implement :interpolate for Color::RGB
7
+ # in order for Interpolation to work
8
+ class Color::RGB
9
+ def interpolate(other, balance)
10
+ mix_with(other, balance * 100.0)
11
+ end
12
+ end
13
+
14
+ # a nice weathermap-style color gradient
15
+ points = {
16
+ 0 => Color::RGB::White,
17
+ 1 => Color::RGB::Lime,
18
+ # 2 => ? (something between Lime and Yellow)
19
+ 3 => Color::RGB::Yellow,
20
+ 4 => Color::RGB::Orange,
21
+ 5 => Color::RGB::Red,
22
+ 6 => Color::RGB::Magenta,
23
+ 7 => Color::RGB::DarkGray
24
+ }
25
+
26
+
27
+ gradient = Interpolation.new(points)
28
+
29
+ # what are the colors of the gradient from 0 to 7
30
+ # in increments of 0.2?
31
+ (0).step(7, 0.2) do |value|
32
+ color = gradient.at(value)
33
+ puts "A value of #{value} means #{color.html}"
34
+ end
35
+
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'interpolate'
3
+ require 'pp'
4
+
5
+
6
+ # a non-linear set of 2D vertexes;
7
+ # the shape changes at each frame
8
+ time_frames = {
9
+ 0 => [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0]], # a horizontal line
10
+ 1 => [[0, 0], [1, 0], [3, 0], [0, 4], [0, 0]], # a triangle
11
+ 2 => [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]], # a square
12
+ 3 => [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0]], # a horizontal line, again
13
+ 4 => [[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]] # a vertical line
14
+ }
15
+
16
+
17
+ paths = Interpolation.new(time_frames)
18
+
19
+ # show the vertex positions in time increments of 0.25
20
+ (0).step(4, 0.25) do |time|
21
+ points = paths.at(time)
22
+ puts ">> At #{time}s, points are:"
23
+ p points
24
+ end
25
+
26
+
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'interpolate'
3
+
4
+ points = {
5
+ 0.000 => 0,
6
+ 0.427 => 1,
7
+ 1.200 => 2,
8
+ 3.420 => 3,
9
+ 27.50 => 4,
10
+ 45.20 => 5,
11
+ 124.4 => 6,
12
+ }
13
+
14
+ zones = Interpolation.new(points)
15
+
16
+ values = [
17
+ -20.2,
18
+ 0.234,
19
+ 65.24,
20
+ 9.234,
21
+ 398.4,
22
+ 4000
23
+ ]
24
+
25
+ values.each do |value|
26
+ zone = zones.at(value).floor
27
+ puts "A value of #{value} falls into zone #{zone}"
28
+ end
@@ -0,0 +1,304 @@
1
+ =begin rdoc
2
+
3
+ Library for generic interpolation objects. Useful for such things as generating
4
+ linear motion between points (or arrays of points), multi-channel color
5
+ gradients, piecewise functions, or even just placing values within intervals.
6
+
7
+ The only requirement is that each interpolation point value must be able to
8
+ figure out how to interpolate itself to its neighbor value(s). Numeric
9
+ objects and uniformly sized arrays are automatically endowed with this
10
+ ability by this gem, but other classes will require an implementation
11
+ of #interpolate. See the second example below for a brief demonstration
12
+ using Color objects.
13
+
14
+ Interpolation objects are constructed with a Hash object, wherein each key
15
+ is a real number value and each value is can respond to #interpolate and
16
+ determine the resulting value based on its neighbor value and the balance
17
+ ratio between the two points.
18
+
19
+ At or below the lower bounds of the interpolation, the result will be equal to
20
+ the value of the lower bounds interpolation point. At or above the upper
21
+ bounds of the graient, the result will be equal to the value of the upper
22
+ bounds interpolation point.
23
+
24
+
25
+ ==Author
26
+
27
+ {Adam Collins}[mailto:adam.w.collins@gmail.com]
28
+
29
+
30
+ ==General Usage
31
+
32
+ Specify the interpolation as a Hash, where keys represent numeric points
33
+ along the gradient and values represent the known values along that gradient.
34
+
35
+ Here's an example for determining which of 7 zones a set of values fall into:
36
+
37
+ require 'rubygems'
38
+ require 'interpolate'
39
+
40
+ points = {
41
+ 0.000 => 0,
42
+ 0.427 => 1,
43
+ 1.200 => 2,
44
+ 3.420 => 3,
45
+ 27.50 => 4,
46
+ 45.20 => 5,
47
+ 124.4 => 6,
48
+ }
49
+
50
+ zones = Interpolation.new(points)
51
+
52
+ values = [
53
+ -20.2,
54
+ 0.234,
55
+ 65.24,
56
+ 9.234,
57
+ 398.4,
58
+ 4000
59
+ ]
60
+
61
+ values.each do |value|
62
+ zone = zones.at(value).floor
63
+ puts "A value of #{value} falls into zone #{zone}"
64
+ end
65
+
66
+
67
+ ==Non-Numeric Gradients
68
+
69
+ For non-Numeric gradient value objects, you'll need to implement :interpolate
70
+ for the class in question. Here's an example using an RGB color gradient with
71
+ the help of the 'color' gem:
72
+
73
+ require 'rubygems'
74
+ require 'interpolate'
75
+ require 'color'
76
+
77
+ # we need to implement :interpolate for Color::RGB
78
+ # in order for Interpolation to work
79
+ class Color::RGB
80
+ def interpolate(other, balance)
81
+ mix_with(other, balance * 100.0)
82
+ end
83
+ end
84
+
85
+ # a nice weathermap-style color gradient
86
+ points = {
87
+ 0 => Color::RGB::White,
88
+ 1 => Color::RGB::Lime,
89
+ # 2 => ? (something between Lime and Yellow)
90
+ 3 => Color::RGB::Yellow,
91
+ 4 => Color::RGB::Orange,
92
+ 5 => Color::RGB::Red,
93
+ 6 => Color::RGB::Magenta,
94
+ 7 => Color::RGB::DarkGray
95
+ }
96
+
97
+
98
+ gradient = Interpolation.new(points)
99
+
100
+ # what are the colors of the gradient from 0 to 7
101
+ # in increments of 0.2?
102
+ (0).step(7, 0.2) do |value|
103
+ color = gradient.at(value)
104
+ puts "A value of #{value} means #{color.html}"
105
+ end
106
+
107
+
108
+ ==Array-based Interpolations
109
+
110
+ Aside from single value gradient points, you can interpolate over uniformly sized
111
+ arrays. Between two interpolation points, let's say +a+ and +b+, the final
112
+ result will be +c+ where +c[0]+ is the interpolation of +a[0]+ and +b[0]+ and
113
+ +c[1]+ is interpolated between +a[1]+ and +b[1]+ and so on up to +c[n]+.
114
+
115
+ Here is an example:
116
+
117
+ require 'rubygems'
118
+ require 'interpolate'
119
+ require 'pp'
120
+
121
+ # a non-linear set of multi-dimensional points;
122
+ # perhaps the location of some actor in relation to time
123
+ time_frames = {
124
+ 0 => [0, 0, 0],
125
+ 1 => [1, 0, 0],
126
+ 2 => [0, 1, 0],
127
+ 3 => [0, 0, 2],
128
+ 4 => [3, 0, 1],
129
+ 5 => [1, 2, 3],
130
+ 6 => [0, 0, 0]
131
+ }
132
+
133
+ path = Interpolation.new(time_frames)
134
+
135
+ # play the actors positions in time increments of 0.25
136
+ (0).step(6, 0.25) do |time|
137
+ position = path.at(time)
138
+ puts ">> At #{time}s, actor is at:"
139
+ p position
140
+ end
141
+
142
+
143
+ ==Nested Array Interpolations
144
+
145
+ As long as each top level array is uniformly sized in the first dimension
146
+ and each nested array is uniformly sized in the second dimension (and so
147
+ on...), multidimensional interpolation point values will just work.
148
+
149
+ Here's an example of a set of 2D points being morphed:
150
+
151
+ require 'rubygems'
152
+ require 'interpolate'
153
+ require 'pp'
154
+
155
+
156
+ # a non-linear set of 2D vertexes;
157
+ # the shape changes at each frame
158
+ time_frames = {
159
+ 0 => [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0]], # a horizontal line
160
+ 1 => [[0, 0], [1, 0], [3, 0], [0, 4], [0, 0]], # a triangle
161
+ 2 => [[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]], # a square
162
+ 3 => [[0, 0], [1, 0], [2, 0], [3, 0], [4, 0]], # a horizontal line, again
163
+ 4 => [[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]] # a vertical line
164
+ }
165
+
166
+
167
+ paths = Interpolation.new(time_frames)
168
+
169
+ # show the vertex positions in time increments of 0.25
170
+ (0).step(4, 0.25) do |time|
171
+ points = paths.at(time)
172
+ puts ">> At #{time}s, points are:"
173
+ p points
174
+ end
175
+
176
+
177
+ ==License
178
+
179
+ Licensed under the MIT license.
180
+
181
+ =end
182
+
183
+
184
+ # all numeric objects should be supported out of the box
185
+ class Numeric
186
+ def interpolate(other, balance)
187
+ left = self.to_f
188
+ right = other.to_f
189
+ delta = (right - left).to_f
190
+ return left + (delta * balance)
191
+ end
192
+ end
193
+
194
+
195
+ # a little more complicated, but there's no reason why we can't
196
+ # interpolate between two equal length arrays as long as each element
197
+ # responds to :interpolate
198
+ class Array
199
+ def interpolate(other, balance)
200
+ if (self.length < 1) then
201
+ raise ArgumentError, "cannot interpolate array with no values"
202
+ end
203
+
204
+ if (self.length != other.length) then
205
+ raise ArgumentError, "cannot interpolate between arrays of different length"
206
+ end
207
+
208
+ final = Array.new
209
+
210
+ self.each_with_index do |left, index|
211
+ unless (left.respond_to? :interpolate) then
212
+ raise "array element does not respond to :interpolate"
213
+ end
214
+
215
+ right = other[index]
216
+
217
+ final[index] = left.interpolate(right, balance)
218
+ end
219
+
220
+ return final
221
+ end
222
+ end
223
+
224
+
225
+ class Interpolation
226
+ VERSION = '0.2.0'
227
+
228
+ def initialize(points = {})
229
+ @points = {}
230
+ add!(points)
231
+ end
232
+
233
+ def add(points = {})
234
+ Interpolation.new(points.merge(@points))
235
+ end
236
+
237
+ def add!(points = {})
238
+ @points.merge!(points)
239
+ normalize_data
240
+ end
241
+
242
+
243
+ def at(point)
244
+ # deal with the two out-of-bounds cases first
245
+ if (point <= @min_point)
246
+ return @data.first.last
247
+ elsif (point >= @max_point)
248
+ return @data.last.last
249
+ end
250
+
251
+ # go through the interpolation intervals, in order, to determine
252
+ # into which this point falls
253
+ 1.upto(@data.length - 1) do |zone|
254
+ left = @data.at(zone - 1)
255
+ right = @data.at(zone)
256
+ zone_range = left.first..right.first
257
+
258
+ if (zone_range.include?(point))
259
+ # what are the points in question?
260
+ left_point = left.first.to_f
261
+ right_point = right.first.to_f
262
+
263
+ # what are the values in question?
264
+ left_value = left.last
265
+ right_value = right.last
266
+
267
+ # span: difference between the left point and right point
268
+ # balance: ratio of right point to left point
269
+ span = right_point - left_point
270
+ balance = (point.to_f - left_point) / span
271
+
272
+ # catch the cases where the point in quesion is
273
+ # on one of the zone's endpoints
274
+ return left_value if (balance == 0.0)
275
+ return right_value if (balance == 1.0)
276
+
277
+ # otherwise, we need to interpolate
278
+ return left_value.interpolate(right_value, balance)
279
+ end
280
+ end
281
+
282
+ # we shouldn't get to this point
283
+ raise "couldn't come up with a value for some reason!"
284
+ end
285
+
286
+ private
287
+
288
+ def normalize_data
289
+ @data = @points.sort
290
+ @min_point = @data.first.first
291
+ @max_point = @data.last.first
292
+
293
+ # make sure that all values respond_to? :interpolate
294
+ @data.each do |point|
295
+ value = point.last
296
+ unless value.respond_to?(:interpolate)
297
+ raise ArgumentError, "found an interpolation point that doesn't respond to :interpolate"
298
+ end
299
+ end
300
+ end
301
+
302
+ end
303
+
304
+
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env ruby1.8 -w
2
+
3
+ require 'test/unit'
4
+ require 'lib/interpolate'
5
+
6
+
7
+ class InterpolationTest < Test::Unit::TestCase
8
+
9
+ DELTA = 1e-7
10
+
11
+ def setup
12
+ decimal_points = {
13
+ 0 => 0,
14
+ 1 => 0.1,
15
+ 2 => 0.2,
16
+ 3 => 0.3,
17
+ 4 => 0.4,
18
+ 5 => 0.5,
19
+ 6 => 0.6,
20
+ 7 => 0.7,
21
+ 8 => 0.8,
22
+ 9 => 0.9,
23
+ 10 => 1
24
+ }
25
+
26
+ array_points = {
27
+ 100 => [1, 10, 100],
28
+ 200 => [5, 50, 500],
29
+ 500 => [10, 100, 1000]
30
+ }
31
+
32
+ @dec_gradient = Interpolation.new(decimal_points)
33
+ @array_gradient = Interpolation.new(array_points)
34
+ end
35
+
36
+
37
+ def test_bad_points
38
+ bad_points = {
39
+ 0 => 4.2,
40
+ 1 => "hello", # not allowed by default
41
+ 2 => 3.4,
42
+ 3 => 4.8
43
+ }
44
+
45
+ assert_raise ArgumentError do
46
+ gradient = Interpolation.new(bad_points)
47
+ end
48
+
49
+ end
50
+
51
+ def test_lower_bounds
52
+ assert_equal(@dec_gradient.at(0), 0)
53
+ assert_equal(@dec_gradient.at(-1), 0)
54
+ assert_equal(@dec_gradient.at(-10), 0)
55
+ assert_equal(@dec_gradient.at(-100), 0)
56
+ end
57
+
58
+ def test_upper_bounds
59
+ assert_equal(@dec_gradient.at(10), 1)
60
+ assert_equal(@dec_gradient.at(100), 1)
61
+ assert_equal(@dec_gradient.at(1000), 1)
62
+ end
63
+
64
+ def test_midpoints
65
+ assert_in_delta(@dec_gradient.at(1.5), 0.15, DELTA)
66
+ assert_in_delta(@dec_gradient.at(2.5), 0.25, DELTA)
67
+ assert_in_delta(@dec_gradient.at(3.5), 0.35, DELTA)
68
+ assert_in_delta(@dec_gradient.at(4.5), 0.45, DELTA)
69
+ assert_in_delta(@dec_gradient.at(5.5), 0.55, DELTA)
70
+ assert_in_delta(@dec_gradient.at(6.5), 0.65, DELTA)
71
+ assert_in_delta(@dec_gradient.at(7.5), 0.75, DELTA)
72
+ assert_in_delta(@dec_gradient.at(8.5), 0.85, DELTA)
73
+ assert_in_delta(@dec_gradient.at(9.5), 0.95, DELTA)
74
+ end
75
+
76
+ def test_precision
77
+ assert_in_delta(@dec_gradient.at(1.5555), 0.15555, DELTA)
78
+ assert_in_delta(@dec_gradient.at(2.5678), 0.25678, DELTA)
79
+ assert_in_delta(@dec_gradient.at(3.5701), 0.35701, DELTA)
80
+ end
81
+
82
+ def test_gradient_add
83
+ new_points = {
84
+ 11 => 1.1,
85
+ 12 => 1.2,
86
+ 13 => 1.3,
87
+ 14 => 1.4,
88
+ 15 => 1.5,
89
+ 16 => 1.6,
90
+ 17 => 1.7,
91
+ 18 => 1.8,
92
+ 19 => 1.9,
93
+ 20 => 2
94
+ }
95
+
96
+ original = @dec_gradient.dup
97
+ expanded = original.add(new_points)
98
+
99
+ assert_equal(original.at(5), 0.5)
100
+ assert_equal(expanded.at(5), 0.5)
101
+
102
+ assert_equal(original.at(15), 1)
103
+ assert_equal(expanded.at(15), 1.5)
104
+ end
105
+
106
+ def test_gradient_add!
107
+ new_points = {
108
+ 11 => 1.1,
109
+ 12 => 1.2,
110
+ 13 => 1.3,
111
+ 14 => 1.4,
112
+ 15 => 1.5,
113
+ 16 => 1.6,
114
+ 17 => 1.7,
115
+ 18 => 1.8,
116
+ 19 => 1.9,
117
+ 20 => 2
118
+ }
119
+
120
+ original = @dec_gradient.dup
121
+ expanded = original.dup
122
+ expanded.add!(new_points)
123
+
124
+ assert_equal(original.at(5), 0.5)
125
+ assert_equal(expanded.at(5), 0.5)
126
+
127
+ assert_equal(original.at(15), 1)
128
+ assert_equal(expanded.at(15), 1.5)
129
+ end
130
+
131
+ def test_array_values
132
+ assert_equal(@array_gradient.at(150), [3, 30, 300])
133
+ assert_equal(@array_gradient.at(200), [5, 50, 500])
134
+ assert_equal(@array_gradient.at(350), [7.5, 75, 750])
135
+ end
136
+
137
+ end
138
+
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: interpolate
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Collins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-24 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.0
23
+ version:
24
+ description: Library for creating generic interpolations objects.
25
+ email: adam.w.collins@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - Manifest.txt
32
+ - README.txt
33
+ files:
34
+ - CHANGELOG
35
+ - MIT-LICENSE
36
+ - Manifest.txt
37
+ - README.txt
38
+ - Rakefile
39
+ - examples/arrays.rb
40
+ - examples/colors.rb
41
+ - examples/nested.rb
42
+ - examples/zones.rb
43
+ - lib/interpolate.rb
44
+ - test/test_all.rb
45
+ has_rdoc: true
46
+ homepage: http://interpolate.rubyforge.org
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --main
50
+ - README.txt
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ requirements: []
66
+
67
+ rubyforge_project: interpolate
68
+ rubygems_version: 1.0.1
69
+ signing_key:
70
+ specification_version: 2
71
+ summary: Useful for such things as generating linear motion between points (or arrays of points), multi-channel color gradients, piecewise functions, or even just placing values within intervals.
72
+ test_files:
73
+ - test/test_all.rb