xrvg 0.0.81 → 0.0.82
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +8 -0
- data/Rakefile +2 -2
- data/examples/colorbezier.rb +38 -0
- data/examples/colorlinear.rb +28 -0
- data/lib/attributable.rb +184 -0
- data/lib/bezier.rb +50 -3
- data/lib/bezierbuilders.rb +1 -1
- data/lib/beziertools.rb +6 -4
- data/lib/color.rb +0 -2
- data/lib/interbezier.rb +5 -4
- data/lib/interpolation.rb +1 -0
- data/lib/parametriclength.rb +1 -3
- data/lib/samplation.rb +3 -4
- data/lib/spiral.rb +20 -6
- data/lib/xrvg.rb +1 -1
- data/test/test_bezier.rb +11 -0
- metadata +5 -2
data/CHANGES
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
= CHANGES
|
2
2
|
|
3
|
+
== 0.0.82 (2008.12.05)
|
4
|
+
=== Content
|
5
|
+
- Debug Ondulation with negative amplitudes
|
6
|
+
- Debug sampler.rand to avoid stack overflow
|
7
|
+
- add .sides method on Bezier class
|
8
|
+
- Debug gem install (attributable.rb missing)
|
9
|
+
- Remove Spiral's dependancy upon Forwardable
|
10
|
+
|
3
11
|
== 0.0.81 (2008.08.26)
|
4
12
|
=== Content
|
5
13
|
- tutorials updated with the new SyncS
|
data/Rakefile
CHANGED
@@ -68,7 +68,7 @@ RDOC_FILES = FileList["README", "CHANGES"]
|
|
68
68
|
|
69
69
|
# Ruby library code.
|
70
70
|
LIB_DIR = "lib"
|
71
|
-
PRE_LIB_FILES = FileList["trace.rb", "samplation.rb", "interpolation.rb", "parametriclength.rb", "utils.rb", "geometry2D.rb", "intersection.rb", "color.rb", "frame.rb", "shape.rb", "render.rb", "shape.rb", "style.rb", "bezier.rb", "bezierspline.rb", "fitting.rb", "bezierbuilders.rb", "beziermotifs.rb", "beziertools.rb", "interbezier.rb", "geovariety.rb", "spiral.rb", "xrvg.rb"]
|
71
|
+
PRE_LIB_FILES = FileList["attributable.rb", "trace.rb", "samplation.rb", "interpolation.rb", "parametriclength.rb", "utils.rb", "geometry2D.rb", "intersection.rb", "color.rb", "frame.rb", "shape.rb", "render.rb", "shape.rb", "style.rb", "bezier.rb", "bezierspline.rb", "fitting.rb", "bezierbuilders.rb", "beziermotifs.rb", "beziertools.rb", "interbezier.rb", "geovariety.rb", "spiral.rb", "xrvg.rb"]
|
72
72
|
LIB_FILES = FileList["#{LIB_DIR}/*.rb"]
|
73
73
|
|
74
74
|
# Example code.
|
@@ -202,7 +202,7 @@ task "gen-blog" do
|
|
202
202
|
# Rake::Task["clobber"].invoke
|
203
203
|
Rake::Task["muse"].invoke
|
204
204
|
# Rake::Task["examples"].invoke; # must be done with emacs
|
205
|
-
Rake::Task["finish"].invoke
|
205
|
+
# Rake::Task["finish"].invoke
|
206
206
|
end
|
207
207
|
|
208
208
|
#---
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'xrvg'
|
2
|
+
include XRVG
|
3
|
+
|
4
|
+
render = SVGRender[:imagesize, "20cm" ]
|
5
|
+
palette = Palette[ :colorlist, [ 0.0, Color.blue,
|
6
|
+
0.1, Color.grey(0.5),
|
7
|
+
0.3, Color.grey(0.25),
|
8
|
+
0.5, Color.grey(0.75),
|
9
|
+
0.7, Color.grey(0.25),
|
10
|
+
0.9, Color.grey(0.5),
|
11
|
+
1.0, Color.yellow],
|
12
|
+
:interpoltype, :simplebezier]
|
13
|
+
style = Style[ :fill, Color.black ]
|
14
|
+
line = Line[ :points, [V2D::O, V2D::X] ]
|
15
|
+
SyncS[line, palette].samples( 100 ) do |point, color|
|
16
|
+
style.fill = color
|
17
|
+
render.add( Circle[:center, point, :radius, 0.01 ], style)
|
18
|
+
end
|
19
|
+
|
20
|
+
curves = []
|
21
|
+
palette.interpolators.each do |interpol|
|
22
|
+
curves << interpol.getcurve
|
23
|
+
end
|
24
|
+
|
25
|
+
curves.each do |curve|
|
26
|
+
render.add( curve, Style[ :stroke, Color.black, :strokewidth, 0.01 ] )
|
27
|
+
curve.gdebug( render )
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
line = Line[ :points, [V2D::O, V2D::X] ].translate( V2D::Y * 0.1 )
|
32
|
+
palette.interpoltype = :linear
|
33
|
+
SyncS[line, palette].samples( 100 ) do |point, color|
|
34
|
+
style.fill = color
|
35
|
+
render.add( Circle[:center, point, :radius, 0.01 ], style)
|
36
|
+
end
|
37
|
+
|
38
|
+
render.end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'xrvg'
|
2
|
+
include XRVG
|
3
|
+
|
4
|
+
render = SVGRender[:imagesize, "3cm" ]
|
5
|
+
palette = Palette[ :colorlist, [ 0.0, Color.blue, 0.25, Color.orange,
|
6
|
+
0.5, Color.yellow, 0.75, Color.green,
|
7
|
+
1.0, Color.blue],
|
8
|
+
:interpoltype, :linear]
|
9
|
+
style = Style[ :fill, Color.black ]
|
10
|
+
line = Line[ :points, [V2D::O, V2D::X] ]
|
11
|
+
SyncS[line, palette].samples( 100 ) do |point, color|
|
12
|
+
style.fill = color
|
13
|
+
render.add( Circle[:center, point, :radius, 0.01 ], style)
|
14
|
+
end
|
15
|
+
|
16
|
+
curves = []
|
17
|
+
palette.interpolators.each do |interpol|
|
18
|
+
points = []
|
19
|
+
interpol.samples( 100 ).each_with_index do |y, index|
|
20
|
+
points << V2D[ index.to_f/100.0, y ]
|
21
|
+
end
|
22
|
+
curves << SimpleBezier[ :support, points ]
|
23
|
+
end
|
24
|
+
|
25
|
+
curves.each do |curve|
|
26
|
+
render.add( curve, Style[ :stroke, Color.black, :strokewidth, 0.01 ] )
|
27
|
+
end
|
28
|
+
render.end
|
data/lib/attributable.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
#
|
2
|
+
# Module to be able to declare attribute, initializing them by default, with type checking
|
3
|
+
# also define syntaxically simpler builder
|
4
|
+
#
|
5
|
+
# See :
|
6
|
+
# - +Object+
|
7
|
+
# - +Attributable+
|
8
|
+
|
9
|
+
#
|
10
|
+
# Object extension to provide the Class[] syntax for building objects, with +Attributable+ module.
|
11
|
+
#
|
12
|
+
# TODO : must be defined only for Class objects !!
|
13
|
+
class Object
|
14
|
+
|
15
|
+
# operator [] definition for shorter and more recognizable object creation syntax.
|
16
|
+
#
|
17
|
+
# Especially useful when creating Attributable dependant objects.
|
18
|
+
# c = Circle[ :center, p, :radius, 0.1 ]
|
19
|
+
def Object.[](*args)
|
20
|
+
return self.new( *args )
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module XRVG
|
25
|
+
# Attribute class used by Attributable module
|
26
|
+
#
|
27
|
+
# Attribute syntax :
|
28
|
+
# attribute :attr1 default_value type
|
29
|
+
# with :
|
30
|
+
# - dvalue nil if no default_value (in that case, attribute is said to be required )
|
31
|
+
# - if type is not specified, default_value must be, and type will be the type of this default_value
|
32
|
+
# type can be an Array of types
|
33
|
+
#
|
34
|
+
# A special :sampled :type is added, to ease declaration of multiform parameter used as Samplation. It can be specified as:
|
35
|
+
# - Array => used as Roller
|
36
|
+
# - Samplable => used as it
|
37
|
+
# - Constant => used as Roller
|
38
|
+
class Attribute
|
39
|
+
attr_accessor :symbol, :default_value, :type
|
40
|
+
|
41
|
+
@@custom_types ||= {}
|
42
|
+
|
43
|
+
def initialize( symbol, default_value, type ) #:nodoc:
|
44
|
+
@symbol = symbol
|
45
|
+
@default_value = default_value
|
46
|
+
@type = type
|
47
|
+
end
|
48
|
+
|
49
|
+
# method to add a "custom" type builder, which acts as a filter on raw attributes to provide a more elaborate one. For example,
|
50
|
+
# see :samplable type, which transforms array and const as samplable objects by encapsulating them in a Roller filter
|
51
|
+
def Attribute.addtype( symbol, builder )
|
52
|
+
@@custom_types[ symbol ] = builder
|
53
|
+
end
|
54
|
+
|
55
|
+
def Attribute.typekey?( symbol )
|
56
|
+
return @@custom_types.key?( symbol )
|
57
|
+
end
|
58
|
+
|
59
|
+
def Attribute.typebuilder( symbol )
|
60
|
+
return @@custom_types[ symbol ]
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
# Attributable module
|
66
|
+
#
|
67
|
+
# Allows class attribute definition in a concise and effective way. Can be viewed as a :attr_accessor extension. See also +Attribute+
|
68
|
+
#
|
69
|
+
# Example :
|
70
|
+
# class A
|
71
|
+
# attribute :a, 1.0; # type is then Float
|
72
|
+
# attribute :b # attribute is required
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# a = A[ :a, 10.0, :b, 2.0 ]
|
76
|
+
# a.a => 10.0
|
77
|
+
module Attributable
|
78
|
+
|
79
|
+
module ClassMethods #:nodoc:
|
80
|
+
def init_attributes
|
81
|
+
if not @attributes
|
82
|
+
@attributes = {}
|
83
|
+
newattributes = (self.superclass.ancestors.include? Attributable) ? self.superclass.attributes : {}
|
84
|
+
@attributes = @attributes.merge( newattributes )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_attribute( attribute )
|
89
|
+
init_attributes
|
90
|
+
@attributes[ attribute.symbol ] = attribute
|
91
|
+
end
|
92
|
+
|
93
|
+
def attributes()
|
94
|
+
init_attributes
|
95
|
+
return @attributes
|
96
|
+
end
|
97
|
+
|
98
|
+
def checkvaluetype( value, type )
|
99
|
+
typeOK = nil
|
100
|
+
types = type
|
101
|
+
types.each do |type|
|
102
|
+
if not type.is_a? Symbol
|
103
|
+
if value.is_a? type
|
104
|
+
typeOK = true
|
105
|
+
break
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
if not typeOK
|
110
|
+
raise( "Attributable::checkvaluetype for class #{self} : default_value #{value.inspect} is not of type #{types.inspect}" )
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def attribute( symbol, default_value=nil, type=nil )
|
115
|
+
if (not type and default_value)
|
116
|
+
type = [default_value.class]
|
117
|
+
elsif type
|
118
|
+
if not type.is_a? Symbol
|
119
|
+
if not type.is_a? Array
|
120
|
+
type = [type]
|
121
|
+
end
|
122
|
+
if default_value
|
123
|
+
checkvaluetype( default_value, type )
|
124
|
+
end
|
125
|
+
else
|
126
|
+
if not Attribute.typekey?( type )
|
127
|
+
raise( "Custom type #{type} has not been defined in Attribute class map: use Attribute.addtype to do it" )
|
128
|
+
end
|
129
|
+
if default_value
|
130
|
+
default_value = Attribute.typebuilder( type ).call( default_value )
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
self.add_attribute( Attribute.new( symbol, default_value, type ) )
|
136
|
+
attr_accessor symbol
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.included( receiver ) #:nodoc:
|
141
|
+
# inherit_attributes; does not work without this because Module is not inherited by subclasses
|
142
|
+
receiver.extend( ClassMethods )
|
143
|
+
end
|
144
|
+
|
145
|
+
def initialize(*args) #:nodoc:
|
146
|
+
# first check if every specified attribute is meaningfull for the class
|
147
|
+
args.foreach do |symbol, value|
|
148
|
+
if not self.class.attributes.key? symbol
|
149
|
+
raise( "Attributable::initialize for class #{self} does not have attribute #{symbol}" )
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# then check specification coherence, and do initialization
|
154
|
+
spec = Hash[ *args ]
|
155
|
+
self.class.attributes.each_pair do |symbol, attr|
|
156
|
+
init_value = nil
|
157
|
+
if spec.key? symbol
|
158
|
+
value = spec[ symbol ]
|
159
|
+
if attr.type
|
160
|
+
if attr.type.is_a? Symbol
|
161
|
+
value = Attribute.typebuilder( attr.type ).call( value )
|
162
|
+
else
|
163
|
+
self.class.checkvaluetype( value, attr.type )
|
164
|
+
end
|
165
|
+
end
|
166
|
+
init_value = value
|
167
|
+
else
|
168
|
+
if attr.default_value == nil
|
169
|
+
raise( "Attributable::initialize for class #{self} : attribute #{symbol} is required : attribute defs #{self.class.attributes.inspect}" )
|
170
|
+
end
|
171
|
+
default_value = attr.default_value
|
172
|
+
# following code is bad, but does the right thing
|
173
|
+
if default_value.is_a? Array
|
174
|
+
default_value = default_value.clone
|
175
|
+
end
|
176
|
+
init_value = default_value
|
177
|
+
end
|
178
|
+
# do init after checking
|
179
|
+
self.method("#{symbol.to_s}=").call(init_value)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
end # end XRVG
|
data/lib/bezier.rb
CHANGED
@@ -183,11 +183,51 @@ class Bezier < Curve
|
|
183
183
|
return self.pointlist()[-1]
|
184
184
|
end
|
185
185
|
|
186
|
-
# shortcut method to build Bezier objects
|
186
|
+
# shortcut method to build Bezier objects from each piece
|
187
187
|
def beziers
|
188
188
|
return self.pieces.map{ |piece| Bezier.single( *piece.data ) }
|
189
189
|
end
|
190
190
|
|
191
|
+
# shortcut method to build Bezier objects from each not regular part
|
192
|
+
def sides
|
193
|
+
result = []
|
194
|
+
# Trace("pieces pointlist:")
|
195
|
+
# self.pieces.each do |piece|
|
196
|
+
# Trace("- #{piece.pointlist(:vector).inspect}")
|
197
|
+
# end
|
198
|
+
v0 = self.pieces[0].pointlist(:vector)[1]
|
199
|
+
v1 = self.pieces[0].pointlist(:vector)[3]
|
200
|
+
subpieces = [self.pieces[0]]
|
201
|
+
self.pieces[1..-1].each do |piece|
|
202
|
+
fv = piece.pointlist(:vector)[1]
|
203
|
+
if not V2D.vequal?( (fv * -1.0).norm, v1.norm, 0.01 )
|
204
|
+
# Trace("fv #{fv.inspect} v1 #{v1.inspect}")
|
205
|
+
result << subpieces
|
206
|
+
subpieces = []
|
207
|
+
end
|
208
|
+
subpieces << piece
|
209
|
+
v1 = piece.pointlist(:vector)[3]
|
210
|
+
end
|
211
|
+
if V2D.vequal?( (v0 * -1.0).norm, v1.norm, 0.01 )
|
212
|
+
# Trace("v0 #{v0.inspect} v1 #{v1.inspect}")
|
213
|
+
if result[0]
|
214
|
+
result[0] = subpieces + result[0]
|
215
|
+
else
|
216
|
+
result = [subpieces]
|
217
|
+
end
|
218
|
+
subpieces = []
|
219
|
+
else
|
220
|
+
result << subpieces
|
221
|
+
end
|
222
|
+
|
223
|
+
newresult = []
|
224
|
+
result.each do |subpieces|
|
225
|
+
newresult << Bezier[ :pieces, subpieces ]
|
226
|
+
end
|
227
|
+
|
228
|
+
return newresult
|
229
|
+
end
|
230
|
+
|
191
231
|
# shortcut method to retrieve a piece as an Bezier object
|
192
232
|
def bezier( index )
|
193
233
|
return Bezier.single( *self.piece( index ).data )
|
@@ -498,7 +538,11 @@ class Bezier < Curve
|
|
498
538
|
if lrange.include?( t )
|
499
539
|
pieceindex = i
|
500
540
|
t = lrange.abscissa( t )
|
501
|
-
|
541
|
+
if self.piece( i ).length.fequal?(0.0)
|
542
|
+
t = 0.0
|
543
|
+
else
|
544
|
+
t = self.piece( i ).parameterfromlength( t )
|
545
|
+
end
|
502
546
|
# Trace("pieceindex #{pieceindex} t #{t}")
|
503
547
|
break
|
504
548
|
end
|
@@ -541,12 +585,13 @@ class Bezier < Curve
|
|
541
585
|
# compute distances rapport
|
542
586
|
r0 = (inter - s01[1]).r / (s02[1] - s01[1]).r
|
543
587
|
r1 = (inter - s11[1]).r / (s12[1] - s11[1]).r
|
588
|
+
# Trace("Bezier.intersections rapports r0 #{r0} r1 #{r1} s0 V2DS #{V2DS[s01[1], s02[1]].inspect} s1 V2DS #{V2DS[s11[1], s12[1]].inspect}")
|
544
589
|
rawresult += [s01[0], s02[0], r0, s11[0], s12[0], r1]
|
545
590
|
end
|
546
591
|
end
|
547
592
|
end
|
548
593
|
|
549
|
-
Trace("rawresult #{rawresult.inspect}")
|
594
|
+
# Trace("Bezier.intersections rawresult #{rawresult.inspect}")
|
550
595
|
|
551
596
|
# compute accurately coords
|
552
597
|
# for the moment, just return mean
|
@@ -555,6 +600,8 @@ class Bezier < Curve
|
|
555
600
|
result += [(t1..t2).sample( r12 ), (t3..t4).sample( r34 )]
|
556
601
|
end
|
557
602
|
|
603
|
+
# Trace("Bezier.intersections result #{result.inspect}")
|
604
|
+
|
558
605
|
return result
|
559
606
|
end
|
560
607
|
|
data/lib/bezierbuilders.rb
CHANGED
@@ -93,7 +93,7 @@ class SimilarMotifIterator < BezierBuilder
|
|
93
93
|
def compute
|
94
94
|
result = []
|
95
95
|
self.curvesampler.samples( self.nmotifs + 1).pairs do |p1,p2|
|
96
|
-
Trace("SimilarMotifIterator::compute p1 #{p1.inspect} p2 #{p2.inspect}")
|
96
|
+
# Trace("SimilarMotifIterator::compute p1 #{p1.inspect} p2 #{p2.inspect}")
|
97
97
|
newbezier = self.motif.similar( (p1..p2) )
|
98
98
|
result += newbezier.data
|
99
99
|
end
|
data/lib/beziertools.rb
CHANGED
@@ -208,7 +208,6 @@ class Ondulation < BezierBuilder
|
|
208
208
|
mabs = (abs1 + abs2)/2.0
|
209
209
|
p1, halfpoint, p2 = self.support.points( [abs1, mabs, abs2] )
|
210
210
|
# Trace("mabs #{mabs} abs1 #{abs1} abs2 #{abs2} halfpoint #{halfpoint.inspect} p1 #{p1.inspect} p2 #{p2.inspect}")
|
211
|
-
# Trace("normal #{@support.normal( mabs )}")
|
212
211
|
halfnormal = self.support.normal( mabs ).norm * ( sens * amplitude * (p2 - p1).length)
|
213
212
|
# Trace("halfnormal #{halfnormal.inspect}")
|
214
213
|
newpoint = halfpoint + halfnormal
|
@@ -216,15 +215,18 @@ class Ondulation < BezierBuilder
|
|
216
215
|
t1 = (tpoint - p1 ) / 6.0
|
217
216
|
t2 = (tpoint - p2 ) / 6.0
|
218
217
|
# Trace("newpoint #{newpoint.inspect} p1 #{p1.inspect} (newpoint - p1) #{(newpoint - p1).inspect}")
|
218
|
+
# TODO: following lines repetitive
|
219
219
|
halftangent = self.support.tangent( mabs ).norm * (newpoint - p1).length / 3.0
|
220
|
-
|
220
|
+
halftangent = self.support.tangent( mabs ).norm * (p2 - p1).length / 3.0
|
221
|
+
# Trace("halftangent #{halftangent.inspect} t1 #{t1.inspect} t2 #{t2.inspect}")
|
221
222
|
return [[:vector, p1, t1, newpoint, -halftangent], [:vector, newpoint, halftangent, p2, t2]]
|
222
223
|
end
|
223
224
|
|
224
225
|
def compute_interpol( abs1, abs2, amplitude, sens )
|
225
|
-
|
226
|
+
orientation = amplitude > 0.0 ? 1.0 : -1.0
|
227
|
+
arc = Bezier.multi( self.compute_arc( abs1, abs2, orientation, sens ) )
|
226
228
|
subsupport = self.support.subbezier( abs1, abs2 )
|
227
|
-
return InterBezier[ :bezierlist, [0.0, subsupport, 1.0, arc] ].sample( amplitude ).data
|
229
|
+
return InterBezier[ :bezierlist, [0.0, subsupport, 1.0, arc] ].sample( amplitude.abs ).data
|
228
230
|
end
|
229
231
|
|
230
232
|
# algo : for each abscissa, 0.0 of the curve (given the normal)
|
data/lib/color.rb
CHANGED
@@ -332,7 +332,6 @@ class Color
|
|
332
332
|
# taken from [[http://en.wikipedia.org/wiki/HSV_color_space]]
|
333
333
|
# h, s, l must be between 0.0 and 1.0
|
334
334
|
def Color.hsla( h, s, l, a)
|
335
|
-
Trace("Color hsla")
|
336
335
|
h = Range.O.trim( h )
|
337
336
|
s = Range.O.trim( s )
|
338
337
|
l = Range.O.trim( l )
|
@@ -511,7 +510,6 @@ class Palette
|
|
511
510
|
end
|
512
511
|
|
513
512
|
def apply_sample( abs ) #:nodoc:
|
514
|
-
Trace("Palette#apply_sample abs #{abs}")
|
515
513
|
return self.color( abs )
|
516
514
|
end
|
517
515
|
|
data/lib/interbezier.rb
CHANGED
@@ -20,16 +20,17 @@ class InterBezier
|
|
20
20
|
indexes.push( index )
|
21
21
|
end
|
22
22
|
|
23
|
+
# TODO: lengthH is useless
|
23
24
|
lengthH = {}
|
24
25
|
alllengths = []
|
25
26
|
beziers.each do |bezier|
|
26
27
|
lengths = bezier.piecelengths
|
27
|
-
Trace("bezier lengths #{lengths.inspect}")
|
28
|
+
# Trace("bezier lengths #{lengths.inspect}")
|
28
29
|
lengthH[ bezier ] = lengths
|
29
30
|
alllengths += lengths
|
30
31
|
end
|
31
32
|
alllengths = Float.sort_float_list( alllengths )
|
32
|
-
Trace("alllengths #{alllengths.inspect}")
|
33
|
+
# Trace("alllengths #{alllengths.inspect}")
|
33
34
|
|
34
35
|
newbezierlist = []
|
35
36
|
beziers.each do |bezier|
|
@@ -42,10 +43,10 @@ class InterBezier
|
|
42
43
|
newbezierlist << newbezier
|
43
44
|
end
|
44
45
|
|
45
|
-
Trace("newbezierlist #{newbezierlist.length}")
|
46
|
+
# Trace("newbezierlist #{newbezierlist.length}")
|
46
47
|
beziers = newbezierlist
|
47
48
|
bezierpointlists = beziers.map {|bezier| bezier.pointlist(:vector) }
|
48
|
-
Trace("bezierpointlists #{bezierpointlists.map {|list| list.length}.inspect}")
|
49
|
+
# Trace("bezierpointlists #{bezierpointlists.map {|list| list.length}.inspect}")
|
49
50
|
pointsequencelist = bezierpointlists.forzip
|
50
51
|
@interpolatorlist = []
|
51
52
|
pointsequencelist.foreach(beziers.size) do |pointsequence|
|
data/lib/interpolation.rb
CHANGED
data/lib/parametriclength.rb
CHANGED
@@ -30,7 +30,6 @@ module ParametricLength
|
|
30
30
|
previous = nil
|
31
31
|
samplelist = [0.0, 0.0]
|
32
32
|
new = V2D[0.0,0.0]
|
33
|
-
previous = nil
|
34
33
|
self.parameter_range.samples( ParametricLength::NSAMPLES ) do |abs|
|
35
34
|
self.pointfromparameter( abs, new )
|
36
35
|
# Trace("compute_length_interpolator: abs #{abs} point #{new.inspect}")
|
@@ -57,10 +56,9 @@ module ParametricLength
|
|
57
56
|
newsamplelist += [sum / @length, abs ]
|
58
57
|
invsamplelist += [abs, sum / @length ]
|
59
58
|
end
|
60
|
-
samplelist = newsamplelist
|
61
59
|
end
|
62
60
|
@abs_interpolator = InterpolatorBinaryTree.new( :samplelist, invsamplelist )
|
63
|
-
return InterpolatorBinaryTree.new( :samplelist,
|
61
|
+
return InterpolatorBinaryTree.new( :samplelist, newsamplelist )
|
64
62
|
end
|
65
63
|
|
66
64
|
def length_interpolator() #:nodoc:
|
data/lib/samplation.rb
CHANGED
@@ -202,11 +202,10 @@ module Samplable
|
|
202
202
|
end
|
203
203
|
|
204
204
|
def rand(nsamples=1,&block)#:nodoc:
|
205
|
-
self.random()
|
206
205
|
if nsamples == 1
|
207
|
-
return sample(
|
206
|
+
return sample( Range.O.rand )
|
208
207
|
else
|
209
|
-
return samples( nsamples, &block )
|
208
|
+
return samples( Range.O.rand(nsamples), &block )
|
210
209
|
end
|
211
210
|
end
|
212
211
|
|
@@ -431,7 +430,7 @@ class RandomFilter < Filter
|
|
431
430
|
rsum = rsizes.sum
|
432
431
|
root = (0.0..(rsize-rsum)).rand
|
433
432
|
|
434
|
-
Trace("mindiffs #{mindiffs.inspect} rsizes #{rsizes.inspect} rsize #{rsize} rsum #{rsum} root #{root}")
|
433
|
+
# Trace("mindiffs #{mindiffs.inspect} rsizes #{rsizes.inspect} rsize #{rsize} rsum #{rsum} root #{root}")
|
435
434
|
|
436
435
|
preresult = []
|
437
436
|
mindiffs.zip( rsizes ) {|mindiff, rsize| preresult.push( mindiff + rsize )}
|
data/lib/spiral.rb
CHANGED
@@ -11,8 +11,6 @@ module XRVG
|
|
11
11
|
#
|
12
12
|
# use compute_radius to compute nsamples reference points, before interpolating with SimpleBezier
|
13
13
|
class GSpiral < Curve
|
14
|
-
extend Forwardable
|
15
|
-
|
16
14
|
attribute :center, V2D::O, V2D
|
17
15
|
attribute :ext, V2D::O + V2D::X, V2D
|
18
16
|
attribute :curvature, 1.0
|
@@ -21,13 +19,29 @@ class GSpiral < Curve
|
|
21
19
|
|
22
20
|
attr_accessor :angle0, :r0, :maxangle
|
23
21
|
|
24
|
-
# setup prefered interface, enq() and deq()...
|
25
|
-
# def_delegator :@q, :push, :enq
|
26
|
-
|
27
22
|
# delegate interfaces unknown for spiral to bezier
|
28
23
|
# :length is computed by ParametricLength
|
29
|
-
|
24
|
+
# extend Forwardable
|
25
|
+
# def_delegators :bezier, :contour, :svg, :viewbox, :acc
|
26
|
+
def contour( *args )
|
27
|
+
return bezier.contour
|
28
|
+
end
|
30
29
|
|
30
|
+
def svg()
|
31
|
+
return bezier.svg
|
32
|
+
end
|
33
|
+
|
34
|
+
def viewbox()
|
35
|
+
return bezier.viewbox
|
36
|
+
end
|
37
|
+
|
38
|
+
def acc()
|
39
|
+
return bezier.acc
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# builder
|
44
|
+
#
|
31
45
|
def initialize( *args )
|
32
46
|
super( *args )
|
33
47
|
@r0, @angle0 = (@ext - @center).coords(:polar)
|
data/lib/xrvg.rb
CHANGED
data/test/test_bezier.rb
CHANGED
@@ -279,6 +279,17 @@ class BezierTest < Test::Unit::TestCase
|
|
279
279
|
# assert_equal( bezier.pointlist, bezier.axesym( V2D::O, V2D[1.0,0.0] ).pointlist )
|
280
280
|
assert_equal( bezier.firstpoint, bezier.axesym( V2D::O, V2D[1.0,0.0] ).firstpoint )
|
281
281
|
end
|
282
|
+
|
283
|
+
def test_sides
|
284
|
+
assert_equal( 1, Circle[].bezier.sides.length )
|
285
|
+
c1 = Ondulation[ :support, LinearBezier[], :freq, 1, :ampl, 2.0 ]
|
286
|
+
c2 = Ondulation[ :support, LinearBezier[], :freq, 1, :ampl, -2.0 ]
|
287
|
+
c = ClosureBezier[ :bezierlist, [c1, c2.reverse] ]
|
288
|
+
# assert_equal( 2, c.sides.length )
|
289
|
+
|
290
|
+
sub = c1.subbezier( 0.5, 0.6 )
|
291
|
+
# assert_equal( 2, (sub + LinearBezier[ :support, [sub.lastpoint, sub.firstpoint] ]).sides.length )
|
292
|
+
end
|
282
293
|
end
|
283
294
|
|
284
295
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: xrvg
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2008-
|
6
|
+
version: 0.0.82
|
7
|
+
date: 2008-12-05 00:00:00 +01:00
|
8
8
|
summary: Ruby vector graphics library
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -31,6 +31,7 @@ authors:
|
|
31
31
|
files:
|
32
32
|
- Rakefile
|
33
33
|
- LICENCE
|
34
|
+
- lib/attributable.rb
|
34
35
|
- lib/bezier.rb
|
35
36
|
- lib/bezierbuilders.rb
|
36
37
|
- lib/beziermotifs.rb
|
@@ -64,6 +65,8 @@ files:
|
|
64
65
|
- examples/circlerecurse1.rb
|
65
66
|
- examples/circlerecurse2.rb
|
66
67
|
- examples/circlerecurseall.rb
|
68
|
+
- examples/colorbezier.rb
|
69
|
+
- examples/colorlinear.rb
|
67
70
|
- examples/euclideangeo.rb
|
68
71
|
- examples/evolution1.rb
|
69
72
|
- examples/evolution2.rb
|