xrvg 0.0.5 → 0.0.6

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.
Files changed (51) hide show
  1. data/CHANGES +8 -0
  2. data/README +1 -1
  3. data/Rakefile +36 -6
  4. data/examples/arciterate1.rb +13 -0
  5. data/examples/arcrecurse1.rb +30 -0
  6. data/examples/arcrecurse2.rb +37 -0
  7. data/examples/circleiterate1.rb +9 -0
  8. data/examples/circleiterate2.rb +11 -0
  9. data/examples/circleiterate3.rb +13 -0
  10. data/examples/circlerecurse1.rb +27 -0
  11. data/examples/circlerecurse2.rb +27 -0
  12. data/examples/circlerecurseall.rb +29 -0
  13. data/examples/euclideangeo.rb +11 -0
  14. data/examples/evolution1.rb +8 -0
  15. data/examples/evolution2.rb +9 -0
  16. data/examples/evolution3.rb +10 -0
  17. data/examples/fuseaugeo.rb +16 -0
  18. data/examples/gradientgeo.rb +21 -0
  19. data/examples/interbeziergeo1.rb +14 -0
  20. data/examples/interbeziergeo2.rb +17 -0
  21. data/examples/interbeziergeo3.rb +17 -0
  22. data/examples/offsetgeo.rb +16 -0
  23. data/lib/bezier.rb +37 -3
  24. data/lib/bezierbuilders.rb +17 -1
  25. data/lib/beziermotifs.rb +11 -4
  26. data/lib/bezierspline.rb +23 -1
  27. data/lib/beziertools.rb +48 -14
  28. data/lib/color.rb +55 -8
  29. data/lib/fitting.rb +2 -2
  30. data/lib/geometry2D.rb +10 -3
  31. data/lib/geovariety.rb +128 -0
  32. data/lib/interbezier.rb +4 -4
  33. data/lib/interpolation.rb +30 -17
  34. data/lib/parametriclength.rb +3 -2
  35. data/lib/render.rb +1 -2
  36. data/lib/samplation.rb +121 -19
  37. data/lib/shape.rb +2 -2
  38. data/lib/spiral.rb +72 -0
  39. data/lib/utils.rb +97 -76
  40. data/lib/xrvg.rb +3 -3
  41. data/test/test_bezier.rb +17 -2
  42. data/test/test_bezierbuilders.rb +1 -1
  43. data/test/test_beziertools.rb +7 -0
  44. data/test/test_color.rb +12 -0
  45. data/test/test_geovariety.rb +105 -0
  46. data/test/test_interpolation.rb +2 -1
  47. data/test/test_render.rb +0 -4
  48. data/test/test_sample.rb +28 -0
  49. data/test/test_spiral.rb +22 -0
  50. data/test/test_utils.rb +65 -40
  51. metadata +26 -2
data/lib/beziertools.rb CHANGED
@@ -63,6 +63,29 @@ class SimpleBezier < BezierBuilder
63
63
  end
64
64
  end
65
65
 
66
+ #
67
+ # Interpolation extension with SimpleBezier
68
+ #
69
+ module Interpolation
70
+
71
+ def compute_simplebezier
72
+ points = self.samplelist.foreach(2).map { |index, value| V2D[index,value] }
73
+ @simplebezier = SimpleBezier[ :support, points ]
74
+ end
75
+
76
+ def getcurve
77
+ if not @simplebezier
78
+ self.compute_simplebezier
79
+ end
80
+ return @simplebezier
81
+ end
82
+
83
+ def simplebezier( dindex )
84
+ return self.getcurve.sample( dindex ).y
85
+ end
86
+
87
+ end
88
+
66
89
 
67
90
  # = Offset bezier builder
68
91
  # == Content
@@ -179,7 +202,31 @@ class Ondulation < BezierBuilder
179
202
  attribute :abscissasampler, (0.0..1.0), Samplable
180
203
  attribute :freq, 10
181
204
 
205
+ # atomic pattern computation
206
+ #
207
+ def compute_arc( abs1, abs2, amplitude, sens )
208
+ mabs = (abs1 + abs2)/2.0
209
+ p1, halfpoint, p2 = self.support.points( [abs1, mabs, abs2] )
210
+ # Trace("mabs #{mabs} abs1 #{abs1} abs2 #{abs2} halfpoint #{halfpoint.inspect} p1 #{p1.inspect} p2 #{p2.inspect}")
211
+ # Trace("normal #{@support.normal( mabs )}")
212
+ halfnormal = self.support.normal( mabs ).norm * ( sens * amplitude * (p2 - p1).length)
213
+ # Trace("halfnormal #{halfnormal.inspect}")
214
+ newpoint = halfpoint + halfnormal
215
+ tpoint = halfpoint + halfnormal * 3.0
216
+ t1 = (tpoint - p1 ) / 6.0
217
+ t2 = (tpoint - p2 ) / 6.0
218
+ # Trace("newpoint #{newpoint.inspect} p1 #{p1.inspect} (newpoint - p1) #{(newpoint - p1).inspect}")
219
+ halftangent = self.support.tangent( mabs ).norm * (newpoint - p1).length / 3.0
220
+ # halftangent = self.support.tangent( mabs ).norm * (p2 - p1).length / 3.0
221
+ return [[:vector, p1, t1, newpoint, -halftangent], [:vector, newpoint, halftangent, p2, t2]]
222
+ end
182
223
 
224
+ def compute_interpol( abs1, abs2, amplitude, sens )
225
+ arc = Bezier.multi( self.compute_arc( abs1, abs2, 1.0, sens ) )
226
+ subsupport = self.support.subbezier( abs1, abs2 )
227
+ return InterBezier[ :bezierlist, [0.0, subsupport, 1.0, arc] ].sample( amplitude ).data
228
+ end
229
+
183
230
  # algo : for each abscissa, 0.0 of the curve (given the normal)
184
231
  # and for each mean abscissa, :amp normal
185
232
  def compute
@@ -188,20 +235,7 @@ class Ondulation < BezierBuilder
188
235
  pieces = []
189
236
  [abscissas.pairs, self.ampl.samples( self.freq )].forzip do |abspair, amplitude|
190
237
  abs1, abs2 = abspair
191
- mabs = (abs1 + abs2)/2.0
192
- p1, halfpoint, p2 = self.support.points( [abs1, mabs, abs2] )
193
- # Trace("mabs #{mabs} abs1 #{abs1} abs2 #{abs2} halfpoint #{halfpoint.inspect} p1 #{p1.inspect} p2 #{p2.inspect}")
194
- # Trace("normal #{@support.normal( mabs )}")
195
- halfnormal = self.support.normal( mabs ).norm * ( sens * amplitude * (p2 - p1).length)
196
- # Trace("halfnormal #{halfnormal.inspect}")
197
- newpoint = halfpoint + halfnormal
198
- tpoint = halfpoint + halfnormal * 3.0
199
- t1 = (tpoint - p1 ) / 6.0
200
- t2 = (tpoint - p2 ) / 6.0
201
- # Trace("newpoint #{newpoint.inspect} p1 #{p1.inspect} (newpoint - p1) #{(newpoint - p1).inspect}")
202
- halftangent = self.support.tangent( mabs ).norm * (newpoint - p1).length / 3.0
203
- # halftangent = self.support.tangent( mabs ).norm * (p2 - p1).length / 3.0
204
- pieces += [[:vector, p1, t1, newpoint, -halftangent], [:vector, newpoint, halftangent, p2, t2]]
238
+ pieces += self.compute_interpol( abs1, abs2, amplitude, sens )
205
239
  sens *= -1.0
206
240
  end
207
241
  return pieces
data/lib/color.rb CHANGED
@@ -3,10 +3,8 @@
3
3
  # - +Palette+
4
4
  # - +Gradient+
5
5
 
6
- require 'geometry2D'; # for vector extension
7
- require 'interpolation'
8
- require 'attributable'
9
6
  require 'utils'
7
+ require 'interpolation'
10
8
  require 'shape'; # for gradient
11
9
 
12
10
  module XRVG
@@ -130,7 +128,7 @@ class Color
130
128
 
131
129
  # return a random color vector, with 1.0 opacity !!
132
130
  # Color.rand => Color[0.2345, 0.987623, 0.4123, 1.0]
133
- def Color.rand( opacity )
131
+ def Color.rand( opacity=1.0 )
134
132
  return Color[Kernel::rand,Kernel::rand,Kernel::rand,opacity]
135
133
  end
136
134
 
@@ -169,6 +167,12 @@ class Color
169
167
  return Color[1.0, 1.0, 1.0, opacity]
170
168
  end
171
169
 
170
+ # return a grey color vector
171
+ def Color.grey(light,opacity=1.0)
172
+ return Color[light, light, light, opacity]
173
+ end
174
+
175
+
172
176
  # build a color vector from hsv parametrization (convert from hsv to rgb) h, s, v being between 0.0 and 1.0
173
177
  #
174
178
  # taken from wikipedia[http://en.wikipedia.org/wiki/HSV_color_space]
@@ -259,7 +263,10 @@ class Color
259
263
 
260
264
  # get svg description of a color
261
265
  def svg
262
- values = self[0..2].map {|v| (255.0 * v).to_i }
266
+ values = self[0..2].map do |v|
267
+ v = Range.O.trim( v )
268
+ (255.0 * v).to_i
269
+ end
263
270
  return "rgb(#{values.join(",")})"
264
271
  end
265
272
 
@@ -275,7 +282,47 @@ end
275
282
  # palette.color( 0.5 ) # => Color.orange
276
283
  class Palette
277
284
  include Attributable
278
- attribute :colorlist
285
+ attribute :colorlist, nil, Array
286
+ attribute :interpoltype, :linear
287
+
288
+ include Samplable
289
+ include Interpolation
290
+
291
+ def initialize( *args )
292
+ super( *args )
293
+ build_interpolators
294
+ end
295
+
296
+ # build an interpolator by color componant
297
+ def build_interpolators()
298
+ vlists = [[],[],[],[]]
299
+ self.colorlist.foreach do |index, color|
300
+ vlists[0] += [index, color.r ]
301
+ vlists[1] += [index, color.g ]
302
+ vlists[2] += [index, color.b ]
303
+ vlists[3] += [index, color.a ]
304
+ end
305
+ @interpolators = vlists.map {|samplelist| Interpolator[ :samplelist, samplelist, :interpoltype, self.interpoltype]}
306
+ end
307
+
308
+ # interpolators accessor (for debugging)
309
+ def interpolators()
310
+ return @interpolators
311
+ end
312
+
313
+ # overloading to reset interpolators if interpoltype changes
314
+ def interpoltype=(value)
315
+ @interpoltype = value
316
+ if @interpolators
317
+ self.build_interpolators
318
+ end
319
+ end
320
+
321
+ # method overloading to delegate computation to componant interpolators
322
+ def interpolate( dindex )
323
+ vs = self.interpolators.map {|inter| inter.interpolate( dindex )}
324
+ return Color[ *vs ]
325
+ end
279
326
 
280
327
  # compute color given float pourcentage.
281
328
  # Palette[ :colorlist, [ 0.0, Color.black, 1.0, Color.white ] ].sample( 0.5 ) => Color[0.5,0.5,0.5,1.O]
@@ -295,14 +342,14 @@ class Palette
295
342
  end
296
343
 
297
344
 
298
- include Samplable
299
- include Interpolation
300
345
 
301
346
  def apply_sample( abs ) #:nodoc:
302
347
  # Trace("Palette#apply_sample abs #{abs}")
303
348
  return self.color( abs )
304
349
  end
305
350
 
351
+
352
+
306
353
  # alias apply_sample color
307
354
  # alias apply_split ? => TODO
308
355
  alias samplelist colorlist
data/lib/fitting.rb CHANGED
@@ -145,13 +145,13 @@ class Fitting
145
145
  maxerror = 0.0
146
146
  container = V2D[]
147
147
  [pointlist, parameters].forzip do |point, parameter|
148
- Trace("point #{point.inspect} parameter #{parameter}")
148
+ # Trace("point #{point.inspect} parameter #{parameter}")
149
149
  error = (point - bezier.point( parameter, container, :parameter )).r
150
150
  if error > maxerror
151
151
  maxerror = error
152
152
  end
153
153
  end
154
- Trace("Fitting.error #{maxerror}")
154
+ # Trace("Fitting.error #{maxerror}")
155
155
  return maxerror
156
156
  end
157
157
 
data/lib/geometry2D.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  # See :
4
4
  # - +V2D+
5
5
 
6
- require 'Attributable'
6
+ require 'attributable'
7
7
 
8
8
  module XRVG
9
9
  #
@@ -127,8 +127,8 @@ class V2D
127
127
  # V2D[0.0,2.0].angle => 0.0
128
128
  def angle
129
129
  r = self.r()
130
- if r == 0
131
- return 0
130
+ if r == 0.0
131
+ return 0.0
132
132
  else
133
133
  unitary = self/r
134
134
  cos, sin = unitary.x, unitary.y
@@ -176,6 +176,13 @@ class V2D
176
176
  return self * 2.0 - other
177
177
  end
178
178
 
179
+ # compute the symetric of point "self" considering (point,v) as symetry axis
180
+ def axesym( point, axev )
181
+ v = self - point
182
+ angle = V2D.angle( v, axev )
183
+ return point + v.rotate( -2.0 * angle )
184
+ end
185
+
179
186
  # coords management between different coord systems (for the moment only euclidian and polar)
180
187
  # V2D[0.0,1.0].coords => [0.0,1.0]
181
188
  # V2D[0.0,1.0].coords(:polar) => [1.0,Math::PI/2.0]
data/lib/geovariety.rb ADDED
@@ -0,0 +1,128 @@
1
+ # File for GeoVariety
2
+ # See (also):
3
+ # - InterBezier
4
+ # - Offsetvariety
5
+ # - FuseauVariety
6
+
7
+ require 'interbezier'
8
+
9
+ module XRVG
10
+
11
+ # = GeoVariety abstract module
12
+ # == Principle
13
+ # Base module to define geometrical spaces or canvas different from simple euclidean one to draw curves on.
14
+ # It provides three different services:
15
+ # - point computation
16
+ # - geodesic computation
17
+ # - arbitrary bezier computation, this one by computing sampling of euclidean curve on the variety, and then fitting point
18
+ # sequence with FitBezierBuilder
19
+ module GeoVariety
20
+
21
+ # must be overriden
22
+ def point( point )
23
+ raise NotImplementedError.new("#{self.class.name}#point is an abstract method.")
24
+ end
25
+
26
+ # must be overriden
27
+ def line( x1, x2, y )
28
+ raise NotImplementedError.new("#{self.class.name}#line is an abstract method.")
29
+ end
30
+
31
+ # see GeoVariety module description for algorithm
32
+ def bezier( pointrange, bezier )
33
+ bezier = bezier.similar( pointrange )
34
+ points = bezier.samples( 20 )
35
+ points = points.map {|point| self.point( point )}
36
+ return FitBezierBuilder[ :points, points ]
37
+ end
38
+ end
39
+
40
+ # = InterBezier GeoVariety implementation
41
+ # == Principle
42
+ # InterBezier defines a surface by the set of every possible curve sample from one interpolated curve to the other.
43
+ # Geodesic corresponds then to one interpolated result, and point to a point of this curve
44
+ class InterBezier
45
+ include GeoVariety
46
+
47
+ # Compute the geodesic curve by doing self.sample with y coord, and then compute point of this curve with length "x"
48
+ def point( point )
49
+ curve = self.sample( point.y )
50
+ return curve.point( point.x )
51
+ end
52
+
53
+ # Compute the geodesic subcurve with y coord between x1 and x2
54
+ def line( x1, x2, y )
55
+ # Trace("interbezier line x1 #{x1} x2 #{x2} y #{y}")
56
+ curve = self.sample( y )
57
+ result = curve.apply_split( x1, x2 )
58
+ # Trace("interbezier line result #{result.inspect}")
59
+ return result
60
+ end
61
+
62
+ end
63
+
64
+ # = OffsetVariety implementation
65
+ # == Principle
66
+ # Geovariety is defined by the set of offset curves from -ampl to +ampl
67
+ # == Extension
68
+ # Parameter could be a :samplable parameter : in that case, ampl will vary
69
+ #
70
+ # Another extension would be to parametrize range straightforwardly
71
+ #
72
+ # Finally, the two previous remarks must be synthetized :-)
73
+ class OffsetVariety
74
+ include Attributable
75
+ attribute :support
76
+ attribute :ampl, nil, Float
77
+
78
+ include GeoVariety
79
+
80
+ # builder: init static offset range with (-self.ampl..self.ampl)
81
+ def initialize( *args )
82
+ super( *args )
83
+ @range = (-self.ampl..self.ampl)
84
+ end
85
+
86
+ # point computed by computing offset curve with ampl y coord mapped onto offset range, and then sampling the curve with x coord
87
+ def point( point )
88
+ curve = Offset[ :support, @support, :ampl, @range.sample( point.y ) ]
89
+ return curve.point( point.x )
90
+ end
91
+
92
+ # subgeodesic computed by computing offset curve with ampl y coord
93
+ def line( x1, x2, y )
94
+ curve = Offset[ :support, @support, :ampl, @range.sample( y ) ]
95
+ return curve.apply_split( x1, x2 )
96
+ end
97
+
98
+ end
99
+
100
+ # = FuseauVariety implementation
101
+ # == Principle
102
+ # Same as OffsetVariety, with Fuseau shape, that is with linearly varying ampl range
103
+ class FuseauVariety
104
+ include Attributable
105
+ attribute :support
106
+ attribute :ampl, nil, Float
107
+
108
+ include GeoVariety
109
+
110
+ def initialize( *args )
111
+ super( *args )
112
+ @range = (-self.ampl..self.ampl)
113
+ end
114
+
115
+ def point( point )
116
+ curve = Offset[ :support, @support, :ampl, (0.0..@range.sample( point.y ))]
117
+ return curve.point( point.x )
118
+ end
119
+
120
+ def line( x1, x2, y )
121
+ curve = Offset[ :support, @support, :ampl, (0.0..@range.sample( y ))]
122
+ return curve.apply_split( x1, x2 )
123
+ end
124
+ end
125
+
126
+ end # XRVG
127
+
128
+ # see geovariety_test to see tests
data/lib/interbezier.rb CHANGED
@@ -24,12 +24,12 @@ class InterBezier
24
24
  alllengths = []
25
25
  beziers.each do |bezier|
26
26
  lengths = bezier.piecelengths
27
- # Trace("bezier lengths #{lengths.inspect}")
27
+ Trace("bezier lengths #{lengths.inspect}")
28
28
  lengthH[ bezier ] = lengths
29
29
  alllengths += lengths
30
30
  end
31
31
  alllengths = Float.sort_float_list( alllengths )
32
- # Trace("alllengths #{alllengths.inspect}")
32
+ Trace("alllengths #{alllengths.inspect}")
33
33
 
34
34
  newbezierlist = []
35
35
  beziers.each do |bezier|
@@ -42,10 +42,10 @@ class InterBezier
42
42
  newbezierlist << newbezier
43
43
  end
44
44
 
45
- # Trace("newbezierlist #{newbezierlist.inspect}")
45
+ Trace("newbezierlist #{newbezierlist.length}")
46
46
  beziers = newbezierlist
47
47
  bezierpointlists = beziers.map {|bezier| bezier.pointlist(:vector) }
48
- # Trace("bezierpointlists #{bezierpointlists.map {|list| list.length}.inspect}")
48
+ Trace("bezierpointlists #{bezierpointlists.map {|list| list.length}.inspect}")
49
49
  pointsequencelist = bezierpointlists.forzip
50
50
  @interpolatorlist = []
51
51
  pointsequencelist.foreach(beziers.size) do |pointsequence|
data/lib/interpolation.rb CHANGED
@@ -3,11 +3,9 @@
3
3
  # See
4
4
  # - +Interpolation+
5
5
  # - +Interpolator+
6
- # - +InterpolatorQuad+
6
+ # - +InterpolatorBinaryTree+
7
7
 
8
8
  require 'utils'
9
- require 'attributable'
10
- require 'samplation'
11
9
 
12
10
  module XRVG
13
11
  # Interpolation module
@@ -29,12 +27,26 @@ module Interpolation
29
27
  raise NotImplementedError.new("#{self.class.name}#samplelist is an abstract method.")
30
28
  end
31
29
 
30
+ # must be the overloaded method to adapt Interpolation
31
+ #
32
+ # is usually provided by a side-effect of a :attribute declaration in including class
33
+ def interpoltype()
34
+ return :linear
35
+ end
36
+
37
+ # overall computation method
38
+ #
39
+ # from an input between 0.0 and 1.0, returns an interpolated value computed by interpolation method deduced from interpoltype
40
+ def interpolate( dindex )
41
+ return method( self.interpoltype ).call( dindex )
42
+ end
43
+
32
44
  # computing method
33
45
  #
34
46
  # from an input between 0.0 and 1.0, returns linear interpolated value
35
47
  #
36
48
  # interpolate uses + and * scalar operators on interpolation values
37
- def interpolate( dindex )
49
+ def linear( dindex )
38
50
  result = nil
39
51
  pindex, pvalue = self.samplelist[0..1]
40
52
  self.samplelist.foreach do |index, value|
@@ -43,7 +55,7 @@ module Interpolation
43
55
  return value
44
56
  end
45
57
  result = pvalue + ((value + (pvalue * (-1.0)) ) * ((dindex - pindex) / (index - pindex )))
46
- Trace("pindex #{pindex} pvalue #{pvalue.inspect} index #{index} value #{value.inspect} dindex #{dindex} result #{result.inspect}")
58
+ # Trace("pindex #{pindex} pvalue #{pvalue.inspect} index #{index} value #{value.inspect} dindex #{dindex} result #{result.inspect}")
47
59
  break
48
60
  end
49
61
  pvalue, pindex = value, index
@@ -61,12 +73,13 @@ end
61
73
  class Interpolator
62
74
  include Attributable
63
75
  attribute :samplelist
76
+ attribute :interpoltype, :linear
64
77
  include Interpolation
65
78
  include Samplable
66
79
  alias apply_sample interpolate
67
80
  end
68
81
 
69
- class QuadRange
82
+ class BinaryTreeRange
70
83
 
71
84
  def initialize( limit, quadleft, quadright, range=nil )
72
85
  @limit = limit
@@ -88,13 +101,13 @@ class QuadRange
88
101
  end
89
102
  end
90
103
 
91
- # QuadTree class
104
+ # BinaryTree class
92
105
  # = Intro
93
106
  # Optim class to look for predefine ranges for a value. Is actually a binary tree data structure, but used as unlinear space partitioner.
94
107
  # = Example
95
- # quad = QuadTree.new( [0.0,1.0, 0.2,0.0, 0.6,1.0, 0.8,0.0, 1.0,1.0] )
108
+ # quad = BinaryTree.new( [0.0,1.0, 0.2,0.0, 0.6,1.0, 0.8,0.0, 1.0,1.0] )
96
109
  # quad.range( 0.5 ); #=> [0.2,0.0,0.6,1.0]
97
- class QuadTree
110
+ class BinaryTree
98
111
 
99
112
  def initialize( samplelist ) #:nodoc:
100
113
  quads = []
@@ -102,7 +115,7 @@ class QuadTree
102
115
  samplelist.foreach(2).pairs do |ppair, pair|
103
116
  pindex, pvalue = ppair
104
117
  index, value = pair
105
- quads << QuadRange.new( nil, nil, nil, [pindex, pvalue, index, value] )
118
+ quads << BinaryTreeRange.new( nil, nil, nil, [pindex, pvalue, index, value] )
106
119
  ends << index
107
120
  end
108
121
  @root = build_quads( quads, ends )
@@ -113,7 +126,7 @@ class QuadTree
113
126
  newends = []
114
127
  index = 0
115
128
  quads.foreach do |quad1, quad2|
116
- newquads << QuadRange.new( ends[2*index], quad1, quad2, nil)
129
+ newquads << BinaryTreeRange.new( ends[2*index], quad1, quad2, nil)
117
130
  newends << ends[2*index + 1]
118
131
  index += 1
119
132
  end
@@ -125,24 +138,24 @@ class QuadTree
125
138
  end
126
139
 
127
140
  # utilitary method to retrieve range of index
128
- # QuadTree.new( [0.0,1.0, 0.2,0.0, 0.6,1.0, 0.8,0.0, 1.0,1.0] ).range( 0.5 ); #=> [0.2,0.0,0.6,1.0]
141
+ # BinaryTree.new( [0.0,1.0, 0.2,0.0, 0.6,1.0, 0.8,0.0, 1.0,1.0] ).range( 0.5 ); #=> [0.2,0.0,0.6,1.0]
129
142
  def range( index )
130
143
  return @root.range( index )
131
144
  end
132
145
  end
133
146
 
134
- # Quad tree interpolator
147
+ # Binary tree interpolator
135
148
  #
136
- # Use QuadTree to retrieve range of values between linear interpolation.
149
+ # Use BinaryTree to retrieve range of values between linear interpolation.
137
150
  #
138
151
  # Used in BezierSpline to compute parameter from length.
139
- class InterpolatorQuad < Interpolator
152
+ class InterpolatorBinaryTree < Interpolator
140
153
 
141
154
  def compute_quad #:nodoc:
142
- @quad = QuadTree.new( self.samplelist )
155
+ @quad = BinaryTree.new( self.samplelist )
143
156
  end
144
157
 
145
- # - first use QuadTree range to retrieve range of dindex,
158
+ # - first use BinaryTree range to retrieve range of dindex,
146
159
  # - then linearly interpolate
147
160
  def interpolate( dindex )
148
161
  if not @quad
@@ -13,6 +13,7 @@ module ParametricLength
13
13
  raise NotImplementedError.new("#{self.class.name}#parameter_range is an abstract method.")
14
14
  end
15
15
 
16
+ # abstract method to compute point from parameter
16
17
  def pointfromparameter( parameter, container )
17
18
  raise NotImplementedError.new("#{self.class.name}#pointfromparameter is an abstract method.")
18
19
  end
@@ -56,8 +57,8 @@ module ParametricLength
56
57
  end
57
58
  samplelist = newsamplelist
58
59
  end
59
- @abs_interpolator = InterpolatorQuad.new( :samplelist, invsamplelist )
60
- return InterpolatorQuad.new( :samplelist, samplelist )
60
+ @abs_interpolator = InterpolatorBinaryTree.new( :samplelist, invsamplelist )
61
+ return InterpolatorBinaryTree.new( :samplelist, samplelist )
61
62
  end
62
63
 
63
64
  def length_interpolator() #:nodoc:
data/lib/render.rb CHANGED
@@ -4,7 +4,6 @@
4
4
  # - +SVGRender+ for effective SVG render
5
5
 
6
6
  require 'color'
7
- require 'attributable'
8
7
  require 'style'
9
8
 
10
9
  module XRVG
@@ -34,7 +33,7 @@ end
34
33
  class SVGRender < Render
35
34
  attribute :filename, "", String
36
35
  attribute :imagesize, "2cm", String
37
- attribute :background, Color.white, [Color, String]
36
+ attribute :background, "white", [Color, String]
38
37
  attr_reader :viewbox
39
38
 
40
39
  # SVGRender builder