xrvg 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,266 @@
1
+ # +BezierSpline+ source
2
+
3
+ # BezierSpline class
4
+ #
5
+ # Internal class to represent a single-piece cubic bezier curve, defined by four points or two point + two vectors.
6
+ # You may never have to use this class. Prefer the use of +Bezier+ class
7
+ class BezierSpline #:nodoc:
8
+
9
+ def BezierSpline.[](*args)
10
+ return BezierSpline.new( *args )
11
+ end
12
+
13
+ def initialize( type, v1, v2, v3, v4 )
14
+ self.checktype( type )
15
+ self.checkvalues( v1, v2, v3, v4 )
16
+ self.initdata( type, v1, v2, v3, v4 )
17
+ end
18
+
19
+ def checkvalues( v1, v2, v3, v4 )
20
+ [v1, v2, v3, v4].each do |v|
21
+ if not v.is_a? V2D
22
+ Kernel::raise( "BezierSpline : init value #{v.inspect} is not a V2D" )
23
+ end
24
+ end
25
+ end
26
+
27
+ def checktype( type )
28
+ if not type == :raw || type == :vector
29
+ Kernel::raise( "BezierSpline : type #{type.inspect} is not :raw or :vector" )
30
+ end
31
+ end
32
+
33
+ def data()
34
+ return [:raw] + self.pointlist
35
+ end
36
+
37
+ def initdata( type, v1, v2, v3, v4 )
38
+ @rawpointlist = nil
39
+ @vectorpointlist = nil
40
+ if type == :raw
41
+ @rawpointlist = [v1, v2, v3, v4]
42
+ elsif
43
+ @vectorpointlist = [v1, v2, v3, v4]
44
+ end
45
+ end
46
+
47
+ def compute_rawpointlist
48
+ # Assert{ @vectorpointlist }
49
+ @rawpointlist = [@vectorpointlist[0], @vectorpointlist[0] + @vectorpointlist[1], @vectorpointlist[2] + @vectorpointlist[3], @vectorpointlist[2]]
50
+ end
51
+
52
+ def compute_vectorpointlist
53
+ # Assert{ @rawpointlist }
54
+ @vectorpointlist = [@rawpointlist[0], @rawpointlist[1] - @rawpointlist[0], @rawpointlist[3], @rawpointlist[2] - @rawpointlist[3]]
55
+ end
56
+
57
+
58
+ def pointlist(type=:raw)
59
+ self.checktype( type )
60
+ if type == :raw
61
+ if not @rawpointlist
62
+ self.compute_rawpointlist
63
+ end
64
+ return @rawpointlist
65
+ elsif type == :vector
66
+ if not @vectorpointlist
67
+ self.compute_vectorpointlist
68
+ end
69
+ return @vectorpointlist
70
+ end
71
+ end
72
+
73
+ # shortcut method to get curve first point
74
+ def firstpoint
75
+ return self.pointlist()[0]
76
+ end
77
+
78
+ # shortcut method to get curve last point
79
+ def lastpoint
80
+ return self.pointlist()[-1]
81
+ end
82
+
83
+
84
+ # -------------------------------------------------------------
85
+ # bezier formula
86
+ # -------------------------------------------------------------
87
+
88
+ def compute_factors
89
+ p1, p2, p3, p4 = self.pointlist
90
+ @factors = [-(p1 - p2 * 3.0 + p3 * 3.0 - p4), (p1 - p2 * 2.0 + p3) * 3.0, (p2 - p1) * 3.0, p1]
91
+ @tfactors = [@factors[0], @factors[1] * 2.0 / 3.0, @factors[2] / 3.0]
92
+ @afactors = [@tfactors[0] * 2.0, @tfactors[1]]
93
+ end
94
+
95
+ # get point from the bezier curve
96
+ # this method use the definition of the bezier curve
97
+ def point( t, result=nil )
98
+ t2 = t * t
99
+ t3 = t2 * t
100
+ if not result
101
+ result = V2D[0.0,0.0]
102
+ end
103
+
104
+ if not @factors
105
+ compute_factors
106
+ end
107
+
108
+ # decomposed because avoid to build useless V2D
109
+ result.x = @factors[3].x + @factors[2].x * t + @factors[1].x * t2 + @factors[0].x * t3
110
+ result.y = @factors[3].y + @factors[2].y * t + @factors[1].y * t2 + @factors[0].y * t3
111
+
112
+ return result
113
+ end
114
+
115
+ # compute the bezier tangent vector
116
+ #
117
+ # Beware that what is actually computed here is 1/3 tangent !!
118
+ def tangent( t, result=nil )
119
+ t2 = t * t
120
+ if not result
121
+ result = V2D[0.0,0.0]
122
+ end
123
+
124
+ if not @factors
125
+ compute_factors
126
+ end
127
+
128
+ # decomposed because avoid to build useless V2D
129
+ result.x = @tfactors[2].x + @tfactors[1].x * t + @tfactors[0].x * t2
130
+ result.y = @tfactors[2].y + @tfactors[1].y * t + @tfactors[0].y * t2
131
+
132
+ return result
133
+ end
134
+
135
+ # compute the acc of bezier curve at t abscissa
136
+ def acc( t, result=nil )
137
+ if not result
138
+ result = V2D[0.0,0.0]
139
+ end
140
+
141
+ if not @factors
142
+ compute_factors
143
+ end
144
+
145
+ result.x = @afactors[1].x + @afactors[0].x * t
146
+ result.y = @afactors[1].y + @afactors[0].y * t
147
+
148
+ return result
149
+ end
150
+
151
+ # compute tangent vectors corresponding to the new subbezier
152
+ # very strange method, but effective
153
+ def subtangents (t1, t2 )
154
+ v1 = self.tangent( t1 ) * (t2 - t1)
155
+ v2 = self.tangent( t2 ) * (t1 - t2)
156
+ return [v1, v2]
157
+ end
158
+
159
+ # compute a subpiece of the current bezier
160
+ # t1 and t2 must correspond to the same atomic bezier
161
+ def subpiece (t1, t2)
162
+ tan1, tan2 = self.subtangents( t1, t2 )
163
+ return BezierSpline.new( :vector, self.point( t1 ), tan1, self.point( t2 ), tan2 )
164
+ end
165
+
166
+ def reverse()
167
+ return BezierSpline[ :raw, *self.pointlist().reverse ]
168
+ end
169
+
170
+ # simple translation operation : translate every point of the piece
171
+ # return a new Bezier
172
+ def translate( v )
173
+ newpoints = self.pointlist.map {|point| point + v}
174
+ return BezierSpline[ :raw, *newpoints ]
175
+ end
176
+
177
+ def gdebug(render)
178
+ p1, pc1, pc2, p2 = self.pointlist()
179
+ v1 = pc1 - p1
180
+ r1 = v1.r / 30.0
181
+ v2 = pc2 - p2
182
+ r2 = v2.r / 30.0
183
+ render.add( Circle[ :center, p1, :radius, r1 ], Style[ :fill, "red" ])
184
+ render.add( Circle[ :center, pc1, :radius, r1 ], Style[ :fill, "red" ])
185
+ render.add( Line[ :points, [p1, pc1] ], Style[ :stroke, "red", :strokewidth, (r1 / 10.0) ])
186
+ render.add( Circle[ :center, p2, :radius, r2 ], Style[ :fill, "red" ])
187
+ render.add( Circle[ :center, pc2, :radius, r1 ], Style[ :fill, "red" ])
188
+ render.add( Line[ :points, [p2, pc2] ], Style[ :stroke, "red", :strokewidth, (r2 / 10.0) ])
189
+ end
190
+
191
+ # -------------------------------------------------------------
192
+ # length computation
193
+ # -------------------------------------------------------------
194
+
195
+
196
+ # compute the length of the bezier curve defined by the points
197
+ #
198
+ # Algo : recursively approximate curve by lines, until length variation is under some epsilon
199
+ #
200
+ # for the moment, just take a fix number of samples, and some it
201
+ def compute_length_interpolator() #:nodoc:
202
+ sum = 0.0
203
+ previous = nil
204
+ samplelist = [0.0, 0.0]
205
+ new = V2D[0.0,0.0]
206
+ previous = nil
207
+ (0.0..1.0).samples( 100 ) do |abs|
208
+ self.point( abs, new )
209
+ if previous
210
+ sum+= (new - previous).r
211
+ samplelist += [abs, sum]
212
+ else
213
+ previous = V2D[0.0,0.0]
214
+ end
215
+ previous.x = new.x
216
+ previous.y = new.y
217
+ end
218
+ @length = samplelist[-1]
219
+
220
+ length_interpolator = nil
221
+ if @length == 0.0
222
+ newsamplelist = [0.0,0.0,1.0,0.0]
223
+ invsamplelist = [0.0,0.0,0.0,1.0]
224
+ else
225
+ newsamplelist = []
226
+ invsamplelist = []
227
+ samplelist.foreach do |abs, sum|
228
+ newsamplelist += [abs, sum / @length]
229
+ invsamplelist += [sum / @length, abs]
230
+ end
231
+ samplelist = newsamplelist
232
+ end
233
+ @abs_interpolator = Interpolator.new( :samplelist, invsamplelist )
234
+ return Interpolator.new( :samplelist, samplelist )
235
+ end
236
+
237
+ def length_interpolator() #:nodoc:
238
+ if @length_interpolator == nil
239
+ @length_interpolator = self.compute_length_interpolator()
240
+ end
241
+ return @length_interpolator
242
+ end
243
+
244
+ def length(t=nil)
245
+ if @length == nil
246
+ self.compute_length()
247
+ end
248
+ if not t
249
+ return @length
250
+ else
251
+ return @abs_interpolator.interpolate( t )
252
+ end
253
+ end
254
+
255
+ def compute_length() #:nodoc:
256
+ self.length_interpolator()
257
+ return @length
258
+ end
259
+
260
+ def parameterfromlength( l ) #:nodoc:
261
+ result = self.length_interpolator.interpolate( l )
262
+ return result
263
+ end
264
+
265
+
266
+ end
data/lib/color.rb CHANGED
@@ -8,26 +8,65 @@ require 'interpolation'
8
8
  require 'attributable'
9
9
  require 'utils'
10
10
  require 'shape'; # for gradient
11
+ require 'matrix'
11
12
 
12
13
  #
13
14
  # Color class
14
15
  #
15
16
  # = Basics
16
- # Class Color derives from Vector, and consists in a 4D vector of (0.0..1.0) values, for red, blue, green, and opacity
17
+ # Class Color consists in a 4D vector of (0.0..1.0) values, for red, blue, green, and opacity
17
18
  # = Utilities
18
19
  # Conversion from hsv and hsl color spaces available (see this link[http://en.wikipedia.org/wiki/HSV_color_space])
19
20
  # = Future
20
21
  # - Must use this library[https://rubyforge.org/projects/color/], to avoid effort duplication
21
22
  # - Must add relative color operations as Nodebox wants to
22
23
  # - Must optimize 4D vector operations (as C extension ?)
23
- class Color < Vector
24
+ class Color
24
25
 
25
26
  # Color builder
26
27
  #
27
28
  # only allows to build 4D vector, with composants between 0.0 and 1.0
28
- def initialize( *args )
29
+ def Color.[]( *args )
29
30
  # TODO : check args number
30
- super( *args )
31
+ Color.new( *args )
32
+ end
33
+
34
+ # builder
35
+ #
36
+ # r, g, b, a must be between 0.0 and 1.0
37
+ def initialize( r, g, b, a)
38
+ @items = [r,g,b,a]
39
+ end
40
+
41
+ # delegation componant indexation method
42
+ def [](index)
43
+ return @items[index]
44
+ end
45
+
46
+ # define addition operation, for interpolation
47
+ def +( other )
48
+ return Color[ self.r + other.r,
49
+ self.g + other.g,
50
+ self.b + other.b,
51
+ self.a + other.a ]
52
+ end
53
+
54
+ # define scalar multiplication, for interpolation
55
+ def *( scalar )
56
+ return Color[ self.r * scalar,
57
+ self.g * scalar,
58
+ self.b * scalar,
59
+ self.a * scalar ]
60
+ end
61
+
62
+ # return [r,g,b,a]
63
+ def composants
64
+ return @items
65
+ end
66
+
67
+ # equality operator
68
+ def ==( other )
69
+ return (self.composants == other.composants)
31
70
  end
32
71
 
33
72
  # return the red composant
@@ -224,7 +263,7 @@ class Palette
224
263
  # "sample" method as defined in Samplable module
225
264
  def color(dindex)
226
265
  result = self.interpolate(dindex)
227
- return Color.elements(result[0..-1],false)
266
+ return result
228
267
  end
229
268
 
230
269
  # return a new palette by reversing the current one
data/lib/geometry2D.rb CHANGED
@@ -1,45 +1,90 @@
1
1
  #
2
- # Contains Ruby Vector class extension.
2
+ # Contains Ruby geometric Vector 2D class.
3
3
  # See :
4
- # - +Vector+
5
- # - +Point+
4
+ # - +V2D+
6
5
 
7
- require 'matrix'
6
+ require 'Attributable'
8
7
 
9
- #
10
- # Vector class extension, to provide several useful "geometrical" services
11
- #
12
- # For example :
13
- # Vector[0.0,2.0].norm => Vector[0.0,1.0]
14
- # Vector[0.0,2.0].angle => 0.0
15
- # Vector[0.0,2.0].ortho => Vector[-2.0,0.0]
16
- # Vector[0.0,2.0].rotate( Math::PI ) => Vector[0.0,-2.0]
17
8
  #
18
- # It could be efficient to define specific 2D vector, to speed up computation.
19
- # It is however not compatible with Color definition, as Vector 4D, and prevent from using this lib in 3D or 4D (with time).
20
- # Must be checked though.
9
+ # 2D vector
21
10
  #
22
- # Another thing is to make this class C extension, to speed up computation.
23
- class Vector
11
+ # V2D class definition, to provide several useful "geometrical" services
12
+ #
13
+ # Extends and somehow redefines Vector class, to speed up computation, as less generic
14
+ #
15
+ # For example :
16
+ # V2D[0.0,2.0].norm => V2D[0.0,1.0]
17
+ # V2D[0.0,2.0].angle => 0.0
18
+ # V2D[0.0,2.0].ortho => V2D[-2.0,0.0]
19
+ # V2D[0.0,2.0].rotate( Math::PI ) => V2D[0.0,-2.0]
20
+ class V2D
24
21
  include Comparable
22
+ include Attributable
23
+ attribute :x, 0.0, Float
24
+ attribute :y, 0.0, Float
25
+
26
+ # create a new 2D vector
27
+ # v = V2D[0.0,0.0]
28
+ def V2D.[](x=0.0,y=0.0)
29
+ return V2D.new(x,y)
30
+ end
31
+
32
+ # set coords
33
+ def xy=(other)
34
+ if other.is_a? Array
35
+ self.x = other[0]
36
+ self.y = other[1]
37
+ else
38
+ self.x = other.x
39
+ self.y = other.y
40
+ end
41
+ end
25
42
 
26
- X = Vector[1.0, 0.0]
27
- Y = Vector[0.0, 1.0]
28
- O = Vector[0.0, 0.0]
43
+ # initialize overloading on Attributable to speed up
44
+ def initialize(x,y) #:nodoc:
45
+ self.x = x
46
+ self.y = y
47
+ end
48
+
49
+ X = V2D[1.0, 0.0]
50
+ Y = V2D[0.0, 1.0]
51
+ O = V2D[0.0, 0.0]
29
52
 
30
- # to optimize for 2D
31
- if nil
53
+ # scalar multiplication
54
+ # V2D[1.0,2.0] * 2.0; #=> V2D[2.0,4.0]
32
55
  def *( scalar )
33
- return Vector[ self[0] * scalar, self[1] * scalar ]
56
+ return V2D[ self.x * scalar, self.y * scalar ]
57
+ end
58
+
59
+ # scalar division
60
+ # V2D[1.0,2.0] / 2.0; #=> V2D[0.5,1.0]
61
+ # ruby checks for dividing by zero
62
+ def /( scalar )
63
+ return V2D[ self.x / scalar, self.y / scalar ]
34
64
  end
35
65
 
66
+ # 2D vector addition
67
+ # V2D[1.0,2.0] + V2D[2.0,1.0]; #=> V2D[3.0,3.0]
36
68
  def +(other)
37
- return Vector[ self[0] + other[0], self[1] + other[1] ]
69
+ return V2D[ self.x + other.x, self.y + other.y ]
70
+ end
71
+
72
+ # 2D vector substraction
73
+ # V2D[1.0,2.0] - V2D[2.0,1.0]; #=> V2D[-1.0,1.0]
74
+ def -(other)
75
+ return V2D[ self.x - other.x, self.y - other.y ]
38
76
  end
77
+
78
+ # 2D vector negative
79
+ # -V2D[1.0,2.0] #=> V2D[-1.0,2.0]
80
+ def -@ ()
81
+ return V2D[ -self.x, -self.y ]
39
82
  end
40
83
 
84
+ # alias for 2D vector negative
85
+ alias reverse -@
41
86
 
42
- # method necessary to make Vector Ranges
87
+ # method necessary to make V2D Ranges
43
88
  #
44
89
  # make <=> on x, then on y
45
90
  def <=>( other )
@@ -51,34 +96,41 @@ class Vector
51
96
  end
52
97
  end
53
98
 
54
- # method necessary to make Vector Ranges
99
+ # method necessary to make V2D Ranges
55
100
  #
56
101
  # simply call succ on each coord
57
102
  def succ()
58
- return Vector[ self.x.succ, self.y.succ ]
103
+ return V2D[ self.x.succ, self.y.succ ]
59
104
  end
60
105
 
106
+ # compute length of 2D vector (r notation to be compatible with Vector)
107
+ def r()
108
+ return Math.hypot( self.x, self.y )
109
+ end
110
+
111
+ # alias for computing 2D vector length
112
+ alias length r
113
+
61
114
  # compute the normalized vector given the current vector
62
- # Vector[0.0,2.0].norm => Vector[0.0,1.0]
115
+ # V2D[0.0,2.0].norm => V2D[0.0,1.0]
63
116
  def norm
64
117
  r = r()
65
118
  if r != 0.0
66
119
  return self / r
67
120
  else
68
- return Vector::O
121
+ return V::O
69
122
  end
70
123
  end
71
124
 
72
125
  # compute the angle of a vector considering x axis.
73
- # Vector[0.0,2.0].angle => 0.0
74
- # must be made in C extension, as expensive
126
+ # V2D[0.0,2.0].angle => 0.0
75
127
  def angle
76
128
  r = self.r()
77
129
  if r == 0
78
130
  return 0
79
131
  else
80
132
  unitary = self/r
81
- cos, sin = unitary[0], unitary[1]
133
+ cos, sin = unitary.x, unitary.y
82
134
  angle = Math.acos( cos )
83
135
  if sin < 0.0
84
136
  angle = -angle
@@ -88,66 +140,44 @@ class Vector
88
140
  end
89
141
 
90
142
  # compute the angle between two vectors
91
- # Vector.angle( Vector[1.0,0.0], Vector[0.0,1.0] ) => Math::PI/2.0
92
- def Vector.angle( v1, v2 )
143
+ # V2D.angle( V2D[1.0,0.0], V2D[0.0,1.0] ) => Math::PI/2.0
144
+ def V2D.angle( v1, v2 )
93
145
  return v1.angle - v2.angle
94
146
  end
95
147
 
148
+ # 2D translation, simply defines as addition
149
+ alias translate +
150
+
96
151
  # scale a vector with another one
97
- # Vector[1.0,2.0].scale( Vector[3.0,4.0] ) => Vector[3.0,8.0]
98
- # v.scale( Vector[a,a] ) <=> v * a
152
+ # V2D[1.0,2.0].scale( V2D[3.0,4.0] ) => V2D[3.0,8.0]
153
+ # v.scale( V2D[a,a] ) <=> v * a
99
154
  def scale( scaler )
100
- return Vector[self.x * scaler.x, self.y * scaler.y ]
155
+ return V2D[self.x * scaler.x, self.y * scaler.y ]
101
156
  end
102
157
 
103
158
  # rotate a 2D vector
104
- # Vector[1.0,0.0].rotate( Math::PI/2.0 ) => Vector[0.0,1.0]
159
+ # V2D[1.0,0.0].rotate( Math::PI/2.0 ) => V2D[0.0,1.0]
105
160
  def rotate( angle )
106
161
  newx = self.x * Math.cos( angle ) - self.y * Math.sin( angle )
107
162
  newy = self.x * Math.sin( angle ) + self.y * Math.cos( angle )
108
- return Vector[ newx, newy ]
163
+ return V2D[ newx, newy ]
109
164
  end
110
165
 
111
166
  # compute the orthogonal vector. Equiv to .rotate( Math::PI/2.0 )
112
- # Vector[1.0,0.0].ortho => Vector[0.0,1.0]
167
+ # V2D[1.0,0.0].ortho => V2D[0.0,1.0]
113
168
  def ortho
114
- return Vector[ -self[1], self[0] ]
115
- end
116
-
117
- # return first coord of a vector
118
- # Vector[1.0,2.0].x => 1.0
119
- def x
120
- return self[0]
169
+ return V2D[ -self.y, self.x ]
121
170
  end
122
171
 
123
- # return second coord of a vector
124
- # Vector[1.0,2.0].y => 2.0
125
- def y
126
- return self[1]
127
- end
128
-
129
- # compute the symetric of vector considered as point, with center of symetrie being other considered as point
130
- # Vector[1.0,2.0].sym( Vector[0.0,0.0] ) => Vector[-1.0,-2.0]
172
+ # compute the symetric of vector considered as point, with center of symetrie being "other" considered as point
173
+ # V2D[1.0,2.0].sym( V2D[0.0,0.0] ) => V2D[-1.0,-2.0]
131
174
  def sym( other )
132
175
  return self * 2.0 - other
133
176
  end
134
177
 
135
- # shortcut method to do
136
- # vector * (1.0 / scalar)
137
- def /( scalar )
138
- return self * (1.0 / scalar)
139
- end
140
-
141
- # more efficient that self * -1.0
142
- def -@ ()
143
- return Vector[ -self[0], -self[1] ]
144
- end
145
-
146
- alias reverse -@
147
-
148
178
  # coords management between different coord systems (for the moment only euclidian and polar)
149
- # Vector[0.0,1.0].coords => [0.0,1.0]
150
- # Vector[0.0,1.0].coords(:polar) => [1.0,Math::PI/2.0]
179
+ # V2D[0.0,1.0].coords => [0.0,1.0]
180
+ # V2D[0.0,1.0].coords(:polar) => [1.0,Math::PI/2.0]
151
181
  def coords(type=:cartesien)
152
182
  if type == :cartesien
153
183
  return [self.x, self.y]
@@ -162,26 +192,26 @@ class Vector
162
192
  end
163
193
 
164
194
  # build a vector from polar coords
165
- def Vector.polar( r, angle )
195
+ def V2D.polar( r, angle )
166
196
  x = r * Math.cos( angle )
167
197
  y = r * Math.sin( angle )
168
- return Vector[x,y]
198
+ return V2D[x,y]
169
199
  end
170
200
 
171
- alias length r
172
- alias translate +
173
- end
174
-
175
- #
176
- # Point class just to have some more meaningful notation, as Point::O
177
- #
178
- class Point < Vector
201
+ # compute 2D inner_product as v1.x * v2.x + v1.y * v2.y
202
+ # V2D[ 1.0, 2.0 ].inner_product( V2D[3.0,4.0] ); #=> 11.0
203
+ def inner_product( other )
204
+ return self.x * other.x + self.y * other.y
205
+ end
179
206
 
180
- O = Point[0.0, 0.0]
207
+ # specific method to test vector equality with specified precision
208
+ def V2D.vequal?( v1, v2, epsilon=0.000000001 )
209
+ return ((v2-v1).r < epsilon)
210
+ end
181
211
 
182
212
  # compute the coord box enclosing every 2D elements considered as points
183
- # Point.viewbox( [Vector[1.0,2.0], Vector[2.0,1.0]] ) => [1.0, 1.0, 2.0, 2.0]
184
- def Point.viewbox (pointlist)
213
+ # Vector.viewbox( [Vector[1.0,2.0], Vector[2.0,1.0]] ) => [1.0, 1.0, 2.0, 2.0]
214
+ def V2D.viewbox (pointlist)
185
215
  if pointlist.size == 0
186
216
  return [0.0, 0.0, 0.0, 0.0]
187
217
  end
@@ -193,15 +223,11 @@ class Point < Vector
193
223
  end
194
224
 
195
225
  # compute dimension of the box enclosing 2D elemnts considered as points
196
- # Point.viewbox( [Vector[1.0,2.0], Vector[10.0,1.0]] ) => [9.0, 1.0]
226
+ # Vector.viewbox( [Vector[1.0,2.0], Vector[10.0,1.0]] ) => [9.0, 1.0]
197
227
  # use +viewvox+
198
- def Point.size (pointlist)
199
- xmin, ymin, xmax, ymax = viewbox( pointlist )
228
+ def V2D.size (pointlist)
229
+ xmin, ymin, xmax, ymax = V2D.viewbox( pointlist )
200
230
  return [xmax - xmin, ymax - ymin]
201
231
  end
202
-
203
232
  end
204
233
 
205
-
206
-
207
-
data/lib/interpolation.rb CHANGED
@@ -23,12 +23,14 @@ module Interpolation
23
23
  # for example, Palette redefines samplelist as
24
24
  # alias samplelist colorlist
25
25
  def samplelist()
26
- return [0.0, 0.0, 1.0, 1.0]
26
+ Kernel::raise("Interpolation::samplelist method must be redefined in subclasses")
27
27
  end
28
28
 
29
29
  # computing method
30
30
  #
31
31
  # from an input between 0.0 and 1.0, returns linear interpolated value
32
+ #
33
+ # interpolate uses + and * scalar operators on interpolation values
32
34
  def interpolate( dindex )
33
35
  result = nil
34
36
  pvalue, pindex = self.samplelist[0..1]
@@ -37,7 +39,7 @@ module Interpolation
37
39
  if dindex == index
38
40
  return value
39
41
  end
40
- result = pvalue + ((value - pvalue ) * ((dindex - pindex) / (index - pindex )))
42
+ result = pvalue + ((value + pvalue * (-1.0) ) * ((dindex - pindex) / (index - pindex )))
41
43
  break
42
44
  end
43
45
  pvalue, pindex = value, index