xrvg 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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