xrvg 0.0.81 → 0.0.82
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.
- 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
|