xrvg 0.0.1 → 0.0.2

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.
@@ -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