xrvg 0.0.6 → 0.0.7
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 +12 -1
- data/Rakefile +30 -8
- data/lib/samplation.rb +10 -2
- data/lib/trace.rb +1 -0
- data/lib/utils.rb +24 -1
- data/test/test_color.rb +19 -13
- data/test/test_utils.rb +10 -0
- metadata +2 -17
- data/lib/bezier.rb +0 -536
- data/lib/bezierbuilders.rb +0 -210
- data/lib/beziermotifs.rb +0 -121
- data/lib/bezierspline.rb +0 -235
- data/lib/beziertools.rb +0 -245
- data/lib/color.rb +0 -401
- data/lib/fitting.rb +0 -203
- data/lib/frame.rb +0 -33
- data/lib/geovariety.rb +0 -128
- data/lib/interbezier.rb +0 -87
- data/lib/render.rb +0 -266
- data/lib/shape.rb +0 -421
- data/lib/spiral.rb +0 -72
- data/lib/style.rb +0 -76
- data/lib/xrvg.rb +0 -46
data/lib/shape.rb
DELETED
@@ -1,421 +0,0 @@
|
|
1
|
-
# shape.rb file
|
2
|
-
# See
|
3
|
-
# - Shape interface
|
4
|
-
# - Curve interface
|
5
|
-
# - Line class
|
6
|
-
# - Circle class
|
7
|
-
require 'utils'
|
8
|
-
require 'frame'
|
9
|
-
require 'geometry2D'
|
10
|
-
|
11
|
-
|
12
|
-
module XRVG
|
13
|
-
# Shape abstract interface
|
14
|
-
# = Intro
|
15
|
-
# To provide a set of services a shape class must provide
|
16
|
-
class Shape
|
17
|
-
include Attributable
|
18
|
-
|
19
|
-
# must return the contour of the shape, of Curve type
|
20
|
-
#
|
21
|
-
# abstract
|
22
|
-
#
|
23
|
-
# not yet used
|
24
|
-
def contour( *args )
|
25
|
-
raise NotImplementedError.new("#{self.class.name}#contour is an abstract method.")
|
26
|
-
end
|
27
|
-
|
28
|
-
# must return the svg description of the shape
|
29
|
-
#
|
30
|
-
# abstract
|
31
|
-
#
|
32
|
-
# must be defined
|
33
|
-
def svg()
|
34
|
-
raise NotImplementedError.new("#{self.class.name}#svg is an abstract method.")
|
35
|
-
end
|
36
|
-
|
37
|
-
# must return the enclosing box of the shape, that is [xmin, ymin, xmax, ymax]
|
38
|
-
#
|
39
|
-
# abstract
|
40
|
-
#
|
41
|
-
# must be defined
|
42
|
-
def viewbox()
|
43
|
-
raise NotImplementedError.new("#{self.class.name}#viewbox is an abstract method.")
|
44
|
-
end
|
45
|
-
|
46
|
-
# compute size of the shape, from viewbox
|
47
|
-
def size()
|
48
|
-
xmin, ymin, xmax, ymax = self.viewbox
|
49
|
-
return [xmax-xmin, ymax-ymin]
|
50
|
-
end
|
51
|
-
|
52
|
-
# return the default style for a Shape instance
|
53
|
-
#
|
54
|
-
# is done on instance, because for Curve for example, strokewidth is proportional to length
|
55
|
-
def default_style()
|
56
|
-
return Style[:fill, Color.black ]
|
57
|
-
end
|
58
|
-
|
59
|
-
# compute the "surface" of the viewbox of the shape
|
60
|
-
#
|
61
|
-
# use size method
|
62
|
-
def surface
|
63
|
-
width, height = self.size
|
64
|
-
return width * height
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
# Curve abstract interface
|
70
|
-
# = Intro
|
71
|
-
# To define a set of services a curve class must provide
|
72
|
-
class Curve < Shape
|
73
|
-
# must compute the point at curve abscissa
|
74
|
-
#
|
75
|
-
# abstract
|
76
|
-
#
|
77
|
-
# must be defined
|
78
|
-
def point( abscissa, container=nil )
|
79
|
-
raise NotImplementedError.new("#{self.class.name}#curve is an abstract method.")
|
80
|
-
end
|
81
|
-
|
82
|
-
# must compute the tangent at curve abscissa
|
83
|
-
#
|
84
|
-
# abstract
|
85
|
-
#
|
86
|
-
# must be defined
|
87
|
-
def tangent( abscissa, container=nil )
|
88
|
-
raise NotImplementedError.new("#{self.class.name}#tangent is an abstract method.")
|
89
|
-
end
|
90
|
-
|
91
|
-
# must compute the acceleration at curve abscissa
|
92
|
-
#
|
93
|
-
# abstract
|
94
|
-
#
|
95
|
-
# must be defined
|
96
|
-
def acc( abscissa, container=nil )
|
97
|
-
raise NotImplementedError.new("#{self.class.name}#acc is an abstract method.")
|
98
|
-
end
|
99
|
-
|
100
|
-
# must return the length at abscissa, or total length if abscissa nil
|
101
|
-
#
|
102
|
-
# abstract
|
103
|
-
#
|
104
|
-
# must be defined
|
105
|
-
def length(abscissa=nil)
|
106
|
-
raise NotImplementedError.new("#{self.class.name}#length is an abstract method.")
|
107
|
-
end
|
108
|
-
|
109
|
-
# default style of a curve, as stroked with stroke width 1% of length
|
110
|
-
def default_style
|
111
|
-
return Style[ :stroke, Color.black, :strokewidth, self.length / 100.0 ]
|
112
|
-
end
|
113
|
-
|
114
|
-
# compute the rotation at curve abscissa, or directly from tangent (for frame computation speed up),
|
115
|
-
# as angle between tangent0 angle and tangent( abscissa ) (or tangent) angle
|
116
|
-
def rotation( abscissa, tangent=nil )
|
117
|
-
if not tangent
|
118
|
-
tangent = self.tangent( abscissa )
|
119
|
-
end
|
120
|
-
return (tangent.angle - self.tangent0_angle)
|
121
|
-
end
|
122
|
-
|
123
|
-
# must compute the scale at curve abscissa, or directly from tangent (for frame computation speed up)
|
124
|
-
# as ratio between tangent0 size and tangent( abscissa ) (or tangent) size
|
125
|
-
def scale( abscissa, tangent=nil )
|
126
|
-
if not tangent
|
127
|
-
tangent = self.tangent( abscissa )
|
128
|
-
end
|
129
|
-
result = 0.0
|
130
|
-
if not self.tangent0_length == 0.0
|
131
|
-
result = (tangent.r / self.tangent0_length)
|
132
|
-
end
|
133
|
-
return result
|
134
|
-
end
|
135
|
-
|
136
|
-
def tangent0
|
137
|
-
if not @tangent0
|
138
|
-
@tangent0 = self.tangent( 0.0 )
|
139
|
-
end
|
140
|
-
return @tangent0
|
141
|
-
end
|
142
|
-
|
143
|
-
# TODO : must be cached in vector
|
144
|
-
def tangent0_angle
|
145
|
-
if not @tangent0_angle
|
146
|
-
@tangent0_angle = self.tangent0.angle
|
147
|
-
end
|
148
|
-
return @tangent0_angle
|
149
|
-
end
|
150
|
-
|
151
|
-
# TODO : must be cached in vector
|
152
|
-
def tangent0_length
|
153
|
-
if not @tangent0_length
|
154
|
-
@tangent0_length = self.tangent0.r
|
155
|
-
end
|
156
|
-
return @tangent0_length
|
157
|
-
end
|
158
|
-
|
159
|
-
# compute frame vector at abscissa t, that is [curve.point( t ), curve.tangent( t ) ]
|
160
|
-
def framev( t )
|
161
|
-
return [self.point( t ), self.tangent( t ) ]
|
162
|
-
end
|
163
|
-
|
164
|
-
# compute frame at abscissa t
|
165
|
-
def frame( t )
|
166
|
-
point, tangent = self.framev( t )
|
167
|
-
return Frame[ :center, point, :vector, tangent, :rotation, self.rotation( nil, tangent ), :scale, self.scale( nil, tangent ) ]
|
168
|
-
end
|
169
|
-
|
170
|
-
# compute normal at abscissa t
|
171
|
-
#
|
172
|
-
# do tangent.ortho
|
173
|
-
def normal( t )
|
174
|
-
return self.tangent( t ).ortho
|
175
|
-
end
|
176
|
-
|
177
|
-
# compute normal acceleration at abscissa t
|
178
|
-
def acc_normal( t )
|
179
|
-
normal = self.normal( t ).norm
|
180
|
-
result = self.acc( t ).inner_product( normal )
|
181
|
-
return result
|
182
|
-
end
|
183
|
-
|
184
|
-
# compute curvature at abscissa t
|
185
|
-
def curvature( t )
|
186
|
-
acc_normal = self.acc_normal( t )
|
187
|
-
if acc_normal == 0.0
|
188
|
-
return 0.0
|
189
|
-
end
|
190
|
-
return 1.0 / (self.tangent( t ).r / acc_normal )
|
191
|
-
end
|
192
|
-
|
193
|
-
# shortcut method to map frames from abscissas
|
194
|
-
def frames (abscissas)
|
195
|
-
return abscissas.map { |abscissa| self.frame( abscissa ) }
|
196
|
-
end
|
197
|
-
|
198
|
-
# shortcut method to map points from abscissas
|
199
|
-
def points (abscissas)
|
200
|
-
result = abscissas.map { |abscissa| self.point( abscissa ) }
|
201
|
-
return result
|
202
|
-
end
|
203
|
-
|
204
|
-
# shortcut method to map tangents from abscissas
|
205
|
-
def tangents (abscissas)
|
206
|
-
return abscissas.map { |abscissa| self.tangent( abscissa ) }
|
207
|
-
end
|
208
|
-
|
209
|
-
# shortcut method, map of normal
|
210
|
-
def normals( indexes )
|
211
|
-
return indexes.map {|i| self.normal( i )}
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
|
217
|
-
# Line class
|
218
|
-
# = Intro
|
219
|
-
# Used to draw polylines and polygons
|
220
|
-
# = Attributes
|
221
|
-
# attribute :points, [V2D[0.0, 0.0], V2D[1.0, 1.0]]
|
222
|
-
# WARNING : getter "points" is not defined, because is defined as Curve.points( abscissa ) !!!
|
223
|
-
# = Example
|
224
|
-
# line = Line[ :points, [V2D::O, V2D::X] ]
|
225
|
-
class Line < Curve
|
226
|
-
attribute :points, [V2D[0.0, 0.0], V2D[1.0, 1.0]]
|
227
|
-
|
228
|
-
def initialize (*args) #:nodoc:
|
229
|
-
super( *args )
|
230
|
-
self.init_tangents
|
231
|
-
end
|
232
|
-
|
233
|
-
def init_tangents #:nodoc:
|
234
|
-
index = 0
|
235
|
-
@tangents = Array.new
|
236
|
-
@points.pairs { |p1, p2|
|
237
|
-
@tangents[ index ] = (p2-p1).norm
|
238
|
-
index += 1
|
239
|
-
}
|
240
|
-
end
|
241
|
-
|
242
|
-
# return the total length of the polyline
|
243
|
-
def length
|
244
|
-
if not @length
|
245
|
-
@length = 0.0
|
246
|
-
@points.pairs do |p1, p2|
|
247
|
-
@length += (p1 - p2).r
|
248
|
-
end
|
249
|
-
end
|
250
|
-
return @length
|
251
|
-
end
|
252
|
-
|
253
|
-
# compute line point at abscissa
|
254
|
-
# Line[ :points, [V2D::O, V2D::X] ].point( 0.3 ) => V2D[0.0,0.3]
|
255
|
-
def point (abscissa, container=nil)
|
256
|
-
container ||= V2D[]
|
257
|
-
piece1 = abscissa.to_int
|
258
|
-
if piece1 == @points.size - 1
|
259
|
-
container.xy = @points[-1]
|
260
|
-
else
|
261
|
-
abscissa -= piece1
|
262
|
-
cpoints = @points.slice( piece1, 2 )
|
263
|
-
container.xy = [(cpoints[0].x..cpoints[1].x).sample( abscissa ),
|
264
|
-
(cpoints[0].y..cpoints[1].y).sample( abscissa )]
|
265
|
-
end
|
266
|
-
return container
|
267
|
-
end
|
268
|
-
|
269
|
-
# redefining to discriminate between @points and map.point
|
270
|
-
def points(arg=nil)
|
271
|
-
if not arg
|
272
|
-
return @points
|
273
|
-
else
|
274
|
-
super(arg)
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
# compute line tangent at abscissa
|
279
|
-
def tangent (abscissa, container=nil)
|
280
|
-
container ||= V2D[]
|
281
|
-
container.xy = @tangents[abscissa.to_int]
|
282
|
-
return container
|
283
|
-
end
|
284
|
-
|
285
|
-
# acc V2D.O
|
286
|
-
def acc( abscissa, container=nil )
|
287
|
-
container ||= V2D[]
|
288
|
-
container.xy = [0.0,0.0]
|
289
|
-
return container
|
290
|
-
end
|
291
|
-
|
292
|
-
# compute viewbox of the line
|
293
|
-
#
|
294
|
-
# simply call V2D.viewbox on :points
|
295
|
-
def viewbox
|
296
|
-
return V2D.viewbox( @points )
|
297
|
-
end
|
298
|
-
|
299
|
-
# translate a line of v offset, v being a vector
|
300
|
-
#
|
301
|
-
# return a new line with every point of :points translated
|
302
|
-
def translate( v )
|
303
|
-
return Line[ :points, @points.map {|ext| ext + v } ]
|
304
|
-
end
|
305
|
-
|
306
|
-
# reverse a line
|
307
|
-
#
|
308
|
-
# return a new line with :points reversed
|
309
|
-
def reverse
|
310
|
-
return Line[ :points, @points.reverse ]
|
311
|
-
end
|
312
|
-
|
313
|
-
# return line svg description
|
314
|
-
def svg
|
315
|
-
path = "M #{points[0].x} #{points[0].y} "
|
316
|
-
@points[1..-1].each { |p|
|
317
|
-
path += "L #{p.x} #{p.y}"
|
318
|
-
}
|
319
|
-
return "<path d=\"" + path + "\"/>"
|
320
|
-
end
|
321
|
-
|
322
|
-
include Samplable
|
323
|
-
alias apply_sample point
|
324
|
-
end
|
325
|
-
|
326
|
-
# Circle class
|
327
|
-
# = Intro
|
328
|
-
# define a circle curve
|
329
|
-
# = Attributes
|
330
|
-
# attribute :center, V2D[0.0,0.0]
|
331
|
-
# attribute :radius, 1.0
|
332
|
-
# attribute :initangle, 0.0
|
333
|
-
# = Example
|
334
|
-
# c = Circle[ :center, V2D::O, :radius, 1.0 ] # equiv Circle[]
|
335
|
-
class Circle < Curve
|
336
|
-
attribute :center, V2D[0.0,0.0]
|
337
|
-
attribute :radius, 1.0
|
338
|
-
attribute :initangle, 0.0
|
339
|
-
|
340
|
-
# Circle builder from points diametraly opposed
|
341
|
-
# Circle.diameter( V2D[-1.0,0.0], V2D[1.0,0.0] ) == Circle[ :center, V2D::O, :radius, 1.0 ]
|
342
|
-
def Circle.diameter( p1, p2 )
|
343
|
-
initangle = ( p1 - p2 ).angle
|
344
|
-
return Circle[ :center, (p1 + p2)/2.0, :radius, (p1 - p2).r/2.0, :initangle, initangle ]
|
345
|
-
end
|
346
|
-
|
347
|
-
# compute length of the circle
|
348
|
-
def length
|
349
|
-
if not @length
|
350
|
-
@length = 2.0 * Math::PI * self.radius
|
351
|
-
end
|
352
|
-
return @length
|
353
|
-
end
|
354
|
-
|
355
|
-
# shortcut method to retun center.x
|
356
|
-
def cx
|
357
|
-
return self.center.x
|
358
|
-
end
|
359
|
-
|
360
|
-
# shortcut method to retun center.y
|
361
|
-
def cy
|
362
|
-
return self.center.y
|
363
|
-
end
|
364
|
-
|
365
|
-
# viewbox of the circle
|
366
|
-
def viewbox
|
367
|
-
return [ self.cx - self.radius,
|
368
|
-
self.cy - self.radius,
|
369
|
-
self.cx + self.radius,
|
370
|
-
self.cy + self.radius ]
|
371
|
-
end
|
372
|
-
|
373
|
-
# size of the circle
|
374
|
-
def size
|
375
|
-
return [ self.radius, self.radius ]
|
376
|
-
end
|
377
|
-
|
378
|
-
def rotate( angle )
|
379
|
-
return Circle[:center, self.center, :radius, self.radius, :initangle, self.initangle + angle]
|
380
|
-
end
|
381
|
-
|
382
|
-
# svg description of the circle
|
383
|
-
def svg
|
384
|
-
template = '<circle cx="%cx%" cy="%cy%" r="%r%"/>'
|
385
|
-
return template.subreplace( {"%cx%" => cx,
|
386
|
-
"%cy%" => cy,
|
387
|
-
"%r%" => radius} )
|
388
|
-
end
|
389
|
-
|
390
|
-
# compute point at abscissa
|
391
|
-
def point (abscissa, container=nil)
|
392
|
-
angle = Range::Angle.sample( abscissa ) + @initangle
|
393
|
-
container ||=V2D[]
|
394
|
-
container.x = self.cx + self.radius * Math.cos( angle )
|
395
|
-
container.y = self.cy + self.radius * Math.sin( angle )
|
396
|
-
return container
|
397
|
-
end
|
398
|
-
|
399
|
-
# compute tangent at abscissa
|
400
|
-
def tangent( abscissa, container=nil )
|
401
|
-
angle = Range::Angle.sample( abscissa ) + @initangle
|
402
|
-
container ||=V2D[]
|
403
|
-
container.x = -self.radius * Math.sin( angle )
|
404
|
-
container.y = self.radius * Math.cos( angle )
|
405
|
-
return container
|
406
|
-
end
|
407
|
-
|
408
|
-
# compute acc at abscissa
|
409
|
-
def acc( abscissa, container=nil )
|
410
|
-
angle = Range::Angle.sample( abscissa ) + @initangle
|
411
|
-
container ||=V2D[]
|
412
|
-
container.x = -self.radius * Math.cos( angle )
|
413
|
-
container.y = -self.radius * Math.sin( angle )
|
414
|
-
return container
|
415
|
-
end
|
416
|
-
|
417
|
-
|
418
|
-
include Samplable
|
419
|
-
alias apply_sample point
|
420
|
-
end
|
421
|
-
end
|
data/lib/spiral.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
# File dedicated to Spiral curves
|
2
|
-
# - Spiral
|
3
|
-
# - SpiralParam
|
4
|
-
# - SpiralFrise
|
5
|
-
|
6
|
-
require 'shape'
|
7
|
-
|
8
|
-
module XRVG
|
9
|
-
|
10
|
-
# abstract class to define spiral types
|
11
|
-
#
|
12
|
-
# use compute_radius to compute nsamples reference points, before interpolating with SimpleBezier
|
13
|
-
class GSpiral < BezierBuilder
|
14
|
-
attribute :center, V2D::O, V2D
|
15
|
-
attribute :ext, V2D::O + V2D::X, V2D
|
16
|
-
attribute :curvature, 1.0
|
17
|
-
attribute :nsamples, 100
|
18
|
-
|
19
|
-
def compute_radius( r0, angle0, curvature, angle )
|
20
|
-
raise NotImplementedError.new("#{self.class.name}#compute_radius is an abstract method.")
|
21
|
-
end
|
22
|
-
|
23
|
-
def maxangle( r0, angle0, curvature )
|
24
|
-
raise NotImplementedError.new("#{self.class.name}#maxangle is an abstract method.")
|
25
|
-
end
|
26
|
-
|
27
|
-
def compute()
|
28
|
-
points = []
|
29
|
-
r0, angle0 = (@ext - @center).coords(:polar)
|
30
|
-
maxangle = self.maxangle( r0, angle0, @curvature )
|
31
|
-
[(r0..0.0), (angle0..maxangle)].samples( self.nsamples ) do |radius, angle|
|
32
|
-
r = self.compute_radius( r0, angle0, @curvature, angle )
|
33
|
-
point = V2D.polar( r, angle )
|
34
|
-
points.push( @center + point )
|
35
|
-
end
|
36
|
-
return SimpleBezier.build( :support, points ).data
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
# at angle angle0, r = r0
|
41
|
-
# at angle angle0 + curvature, r = 0.0
|
42
|
-
class SpiralLinear < GSpiral
|
43
|
-
|
44
|
-
def maxangle( r0, angle0, curvature )
|
45
|
-
return (angle0 + curvature)
|
46
|
-
end
|
47
|
-
|
48
|
-
def compute_radius( r0, angle0, curvature, angle )
|
49
|
-
return r0 * (1.0 - ( 1.0 + (Math.exp( - 10.0 * ( angle- angle0) / curvature ) ) ) * ( angle - angle0 ) /curvature )
|
50
|
-
# return r0 * (1.0 - ( angle - angle0 ) /curvature )
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
# curvature is in number of tour before center % extremity
|
56
|
-
class SpiralLog < GSpiral
|
57
|
-
|
58
|
-
def nsamples
|
59
|
-
return (curvature * 15.0).to_i
|
60
|
-
end
|
61
|
-
|
62
|
-
def compute_radius( r0, angle0, curvature, angle )
|
63
|
-
return r0 * Math.exp( -(angle-angle0) / curvature )
|
64
|
-
end
|
65
|
-
|
66
|
-
def maxangle( r0, angle0, curvature )
|
67
|
-
return angle0 - curvature * Math.log( 0.001 )
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
end #XRVG
|
72
|
-
|
data/lib/style.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# See +Style+
|
3
|
-
#
|
4
|
-
require 'attributable'
|
5
|
-
require 'utils'
|
6
|
-
require 'color'
|
7
|
-
|
8
|
-
module XRVG
|
9
|
-
#
|
10
|
-
# Style class
|
11
|
-
#
|
12
|
-
# Used to define the way an object has to be rendered.
|
13
|
-
# For the moment, only the following style attributes are really useful :
|
14
|
-
# - attribute :fill, "none", [String, Color, Gradient]
|
15
|
-
# - attribute :stroke, "none", [String, Color, Gradient]
|
16
|
-
# - attribute :strokewidth, 1.0
|
17
|
-
#
|
18
|
-
# For example :
|
19
|
-
# render.add( Circle[], Style[ :fill, Color.red ] )
|
20
|
-
# render.add( Circle[], Style[ :stroke, Color.red ] )
|
21
|
-
class Style
|
22
|
-
include Attributable
|
23
|
-
# attribute :opacity, 1.0
|
24
|
-
attribute :fill, "none", [String, Color, Gradient]
|
25
|
-
# attribute :fillopacity, 1.0
|
26
|
-
attribute :stroke, "none", [String, Color, Gradient]
|
27
|
-
attribute :strokewidth, 1.0
|
28
|
-
# attribute :strokeopacity, 1.0
|
29
|
-
|
30
|
-
def fillopacity()
|
31
|
-
if @fill.is_a? Color
|
32
|
-
return @fill.a
|
33
|
-
end
|
34
|
-
return 1.0
|
35
|
-
end
|
36
|
-
|
37
|
-
def strokeopacity()
|
38
|
-
if @stroke.is_a? Color
|
39
|
-
return @stroke.a
|
40
|
-
end
|
41
|
-
return 1.0
|
42
|
-
end
|
43
|
-
|
44
|
-
|
45
|
-
def svgfill
|
46
|
-
if fill.is_a? Color
|
47
|
-
return fill.svg
|
48
|
-
elsif fill.is_a? Gradient
|
49
|
-
return "%fillgradient%"
|
50
|
-
else
|
51
|
-
return fill
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def svgstroke
|
56
|
-
if stroke.is_a? Color
|
57
|
-
return stroke.svg
|
58
|
-
elsif stroke.is_a? Gradient
|
59
|
-
return "%strokegradient%"
|
60
|
-
else
|
61
|
-
return stroke
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def svgline
|
66
|
-
template = 'style="opacity:%opacity%;fill:%fill%;fill-opacity:%fillopacity%;stroke:%stroke%;stroke-width:%strokewidth%;stroke-opacity:%strokeopacity%"'
|
67
|
-
|
68
|
-
return template.subreplace( {"%opacity%" => 1.0,
|
69
|
-
"%fill%" => svgfill,
|
70
|
-
"%fillopacity%" => fillopacity,
|
71
|
-
"%stroke%" => svgstroke,
|
72
|
-
"%strokewidth%" => strokewidth,
|
73
|
-
"%strokeopacity%" => strokeopacity} )
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
data/lib/xrvg.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# This file has to be included if you want to start a XRVG script
|
2
|
-
#
|
3
|
-
# Please refer to README for XRVG introduction
|
4
|
-
|
5
|
-
# XRVG version (used in rakefile)
|
6
|
-
XRVG_VERSION = "0.0.6"
|
7
|
-
|
8
|
-
# XRVG namespace
|
9
|
-
module XRVG
|
10
|
-
end
|
11
|
-
|
12
|
-
# Standard Ruby extensions
|
13
|
-
require 'enumerator'
|
14
|
-
|
15
|
-
# XRVG Infrastructure
|
16
|
-
require 'trace'
|
17
|
-
|
18
|
-
# XRVG new mixins
|
19
|
-
require 'samplation'
|
20
|
-
require 'attributable'
|
21
|
-
require 'interpolation'
|
22
|
-
require 'parametriclength'
|
23
|
-
|
24
|
-
# XRVG base class extensions
|
25
|
-
require 'utils'
|
26
|
-
require 'geometry2D'
|
27
|
-
|
28
|
-
# XRVG base classes
|
29
|
-
require 'color'
|
30
|
-
require 'frame'
|
31
|
-
require 'shape'
|
32
|
-
require 'render'
|
33
|
-
require 'bezier'
|
34
|
-
|
35
|
-
# XRVG extensions
|
36
|
-
require 'fitting'
|
37
|
-
require 'bezierbuilders'
|
38
|
-
require 'beziermotifs'
|
39
|
-
require 'beziertools'
|
40
|
-
require 'interbezier'
|
41
|
-
require 'geovariety'
|
42
|
-
require 'spiral'
|
43
|
-
# require 'graph'
|
44
|
-
|
45
|
-
|
46
|
-
|