xrvg 0.0.1 → 0.0.2
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 +34 -0
- data/README +2 -2
- data/Rakefile +111 -29
- data/examples/bezierbasic.rb +7 -0
- data/examples/bezierbasicvector.rb +7 -0
- data/examples/foreach.rb +1 -1
- data/examples/geodash.rb +8 -0
- data/examples/geodash2.rb +8 -0
- data/examples/hellocrown.rb +1 -1
- data/examples/hellocrown2.rb +1 -1
- data/examples/hellocrownrecurse.rb +1 -1
- data/examples/multibezierbasic.rb +8 -0
- data/examples/randomdash.rb +8 -0
- data/examples/range_examples.rb +16 -0
- data/examples/range_examples2.rb +10 -0
- data/examples/sample.rb +4 -2
- data/examples/simpledash.rb +8 -0
- data/examples/uplets.rb +1 -1
- data/lib/bezier.rb +461 -0
- data/lib/bezierspline.rb +266 -0
- data/lib/color.rb +44 -5
- data/lib/geometry2D.rb +116 -90
- data/lib/interpolation.rb +4 -2
- data/lib/samplation.rb +16 -10
- data/lib/shape.rb +101 -53
- data/lib/style.rb +13 -12
- data/lib/utils.rb +4 -3
- data/lib/xrvg.rb +2 -3
- data/test/test_bezier.rb +151 -0
- data/test/test_geometry2D.rb +38 -25
- data/test/test_shape.rb +67 -0
- data/test/test_utils.rb +45 -0
- metadata +28 -14
- data/examples/helloworld.rb +0 -5
data/lib/samplation.rb
CHANGED
@@ -51,18 +51,18 @@ module FloatFunctor
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# hook for Array
|
54
|
-
def compute( indata, type )
|
55
|
-
return self.apply( self.modify( indata ), type )
|
54
|
+
def compute( indata, type, &block )
|
55
|
+
return self.apply( self.modify( indata ), type, &block )
|
56
56
|
end
|
57
57
|
|
58
58
|
# hook for rand()
|
59
59
|
def process( indata, type, &block )
|
60
|
-
outdata = self.compute( indata, type )
|
61
60
|
if not block
|
61
|
+
outdata = self.compute( indata, type )
|
62
62
|
# Trace("Samplable#trigger object #{self.inspect} indata #{indata.inspect} outdata #{outdata.inspect}")
|
63
63
|
return outdata
|
64
64
|
else
|
65
|
-
|
65
|
+
self.compute( indata, type, &block )
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -101,6 +101,7 @@ module FloatFunctor
|
|
101
101
|
# it is a registration interface
|
102
102
|
#
|
103
103
|
# must not be overloaded
|
104
|
+
|
104
105
|
# must be refactored with some meta hooks
|
105
106
|
def applyhash
|
106
107
|
result = {}
|
@@ -110,12 +111,12 @@ module FloatFunctor
|
|
110
111
|
end
|
111
112
|
|
112
113
|
# must not be overloaded (apart from Samplable containers)
|
113
|
-
def apply( data, type )
|
114
|
+
def apply( data, type, &block )
|
114
115
|
@applyhash = self.applyhash
|
115
116
|
if not @applyhash.key? type
|
116
117
|
Kernel::Raise("FloatFunctor::apply no regsitration for type #{type} and object #{object.inspect}")
|
117
118
|
else
|
118
|
-
return self.send(@applyhash[type], data )
|
119
|
+
return self.send(@applyhash[type], data, &block )
|
119
120
|
end
|
120
121
|
end
|
121
122
|
|
@@ -250,12 +251,17 @@ module Samplable
|
|
250
251
|
# to be overloaded if needed
|
251
252
|
#
|
252
253
|
# called by FloatFunctor apply method
|
253
|
-
def apply_samples( inputs )
|
254
|
-
|
254
|
+
def apply_samples( inputs, &block )
|
255
|
+
if not block
|
256
|
+
return inputs.map {|abs| self.apply_sample( abs ) }
|
257
|
+
else
|
258
|
+
container = self.apply_sample( inputs[0] ); yield container;
|
259
|
+
inputs[1..-1].each {|abs| yield self.apply_sample( abs, container ) }
|
260
|
+
end
|
255
261
|
end
|
256
262
|
|
257
263
|
# to be overloaded if needed
|
258
|
-
def apply_sample( abs )
|
264
|
+
def apply_sample( abs, container=nil )
|
259
265
|
return abs
|
260
266
|
end
|
261
267
|
|
@@ -296,7 +302,7 @@ module Splittable
|
|
296
302
|
|
297
303
|
# must not be overriden
|
298
304
|
def split( abs1, abs2 )
|
299
|
-
return self.apply( self.
|
305
|
+
return self.apply( self.modify( [abs1,abs2] ), :split ).pop
|
300
306
|
end
|
301
307
|
|
302
308
|
# to be overloaded if needed
|
data/lib/shape.rb
CHANGED
@@ -74,7 +74,7 @@ class Curve < Shape
|
|
74
74
|
# abstract
|
75
75
|
#
|
76
76
|
# must be defined
|
77
|
-
def point( abscissa )
|
77
|
+
def point( abscissa, container=nil )
|
78
78
|
Kernel::raise("Curve::point must be redefined in subclasses")
|
79
79
|
end
|
80
80
|
|
@@ -83,7 +83,7 @@ class Curve < Shape
|
|
83
83
|
# abstract
|
84
84
|
#
|
85
85
|
# must be defined
|
86
|
-
def tangent( abscissa )
|
86
|
+
def tangent( abscissa, container=nil )
|
87
87
|
Kernel::raise("Curve::tangent must be redefined in subclasses")
|
88
88
|
end
|
89
89
|
|
@@ -92,28 +92,10 @@ class Curve < Shape
|
|
92
92
|
# abstract
|
93
93
|
#
|
94
94
|
# must be defined
|
95
|
-
def acc( abscissa )
|
95
|
+
def acc( abscissa, container=nil )
|
96
96
|
Kernel::raise("Curve::acc must be redefined in subclasses")
|
97
97
|
end
|
98
98
|
|
99
|
-
# must compute the rotation at curve abscissa
|
100
|
-
#
|
101
|
-
# abstract
|
102
|
-
#
|
103
|
-
# must be defined
|
104
|
-
def rotation( abscissa )
|
105
|
-
Kernel::raise("Curve::rotation must be redefined in subclasses")
|
106
|
-
end
|
107
|
-
|
108
|
-
# must compute the scale at curve abscissa
|
109
|
-
#
|
110
|
-
# abstract
|
111
|
-
#
|
112
|
-
# must be defined
|
113
|
-
def scale( abscissa )
|
114
|
-
Kernel::raise("Curve::scale must be redefined in subclasses")
|
115
|
-
end
|
116
|
-
|
117
99
|
# must return the length at abscissa, or total length if abscissa nil
|
118
100
|
#
|
119
101
|
# abstract
|
@@ -127,10 +109,61 @@ class Curve < Shape
|
|
127
109
|
def default_style
|
128
110
|
return Style[ :stroke, Color.black, :strokewidth, self.length / 100.0 ]
|
129
111
|
end
|
112
|
+
|
113
|
+
# compute the rotation at curve abscissa, or directly from tangent (for frame computation speed up),
|
114
|
+
# as angle between tangent0 angle and tangent( abscissa ) (or tangent) angle
|
115
|
+
def rotation( abscissa, tangent=nil )
|
116
|
+
if not tangent
|
117
|
+
tangent = self.tangent( abscissa )
|
118
|
+
end
|
119
|
+
return (tangent.angle - self.tangent0_angle)
|
120
|
+
end
|
121
|
+
|
122
|
+
# must compute the scale at curve abscissa, or directly from tangent (for frame computation speed up)
|
123
|
+
# as ratio between tangent0 size and tangent( abscissa ) (or tangent) size
|
124
|
+
def scale( abscissa, tangent=nil )
|
125
|
+
if not tangent
|
126
|
+
tangent = self.tangent( abscissa )
|
127
|
+
end
|
128
|
+
result = 0.0
|
129
|
+
if not self.tangent0_length == 0.0
|
130
|
+
result = (tangent.r - self.tangent0_length)
|
131
|
+
end
|
132
|
+
return result
|
133
|
+
end
|
134
|
+
|
135
|
+
def tangent0
|
136
|
+
if not @tangent0
|
137
|
+
@tangent0 = self.tangent( 0.0 )
|
138
|
+
end
|
139
|
+
return @tangent0
|
140
|
+
end
|
141
|
+
|
142
|
+
# TODO : must be cached in vector
|
143
|
+
def tangent0_angle
|
144
|
+
if not @tangent0_angle
|
145
|
+
@tangent0_angle = self.tangent0.angle
|
146
|
+
end
|
147
|
+
return @tangent0_angle
|
148
|
+
end
|
149
|
+
|
150
|
+
# TODO : must be cached in vector
|
151
|
+
def tangent0_length
|
152
|
+
if not @tangent0_length
|
153
|
+
@tangent0_length = self.tangent0.r
|
154
|
+
end
|
155
|
+
return @tangent0_length
|
156
|
+
end
|
130
157
|
|
158
|
+
# compute frame vector at abscissa t, that is [curve.point( t ), curve.tangent( t ) ]
|
159
|
+
def framev( t )
|
160
|
+
return [curve.point( t ), curve.tangent( t ) ]
|
161
|
+
end
|
162
|
+
|
131
163
|
# compute frame at abscissa t
|
132
164
|
def frame( t )
|
133
|
-
|
165
|
+
point, tangent = self.framev( t )
|
166
|
+
return Frame[ :center, point, :vector, tangent, :rotation, self.rotation( nil, tangent ), :scale, self.scale( nil, tangent ) ]
|
134
167
|
end
|
135
168
|
|
136
169
|
# compute normal at abscissa t
|
@@ -149,10 +182,11 @@ class Curve < Shape
|
|
149
182
|
|
150
183
|
# compute curvature at abscissa t
|
151
184
|
def curvature( t )
|
152
|
-
|
185
|
+
acc_normal = self.acc_normal( t )
|
186
|
+
if acc_normal == 0.0
|
153
187
|
return 0.0
|
154
188
|
end
|
155
|
-
return 1.0 / (self.tangent( t ).r /
|
189
|
+
return 1.0 / (self.tangent( t ).r / acc_normal )
|
156
190
|
end
|
157
191
|
|
158
192
|
# shortcut method to map frames from abscissas
|
@@ -171,17 +205,23 @@ class Curve < Shape
|
|
171
205
|
return abscissas.map { |abscissa| self.tangent( abscissa ) }
|
172
206
|
end
|
173
207
|
|
208
|
+
# shortcut method, map of normal
|
209
|
+
def normals( indexes )
|
210
|
+
return indexes.map {|i| self.normal( i )}
|
211
|
+
end
|
212
|
+
|
174
213
|
end
|
175
214
|
|
176
215
|
# Line class
|
177
216
|
# = Intro
|
178
217
|
# Used to draw polylines and polygons
|
179
218
|
# = Attributes
|
180
|
-
# attribute :
|
219
|
+
# attribute :points, [V2D[0.0, 0.0], V2D[1.0, 1.0]]
|
220
|
+
# WARNING : getter "points" is not defined, because is defined as Curve.points( abscissa ) !!!
|
181
221
|
# = Example
|
182
|
-
# line = Line[ :
|
222
|
+
# line = Line[ :points, [V2D::O, V2D::X] ]
|
183
223
|
class Line < Curve
|
184
|
-
attribute :
|
224
|
+
attribute :points, [V2D[0.0, 0.0], V2D[1.0, 1.0]]
|
185
225
|
|
186
226
|
def initialize (*args) #:nodoc:
|
187
227
|
super( *args )
|
@@ -191,7 +231,7 @@ class Line < Curve
|
|
191
231
|
def init_tangents #:nodoc:
|
192
232
|
index = 0
|
193
233
|
@tangents = Array.new
|
194
|
-
|
234
|
+
@points.pairs { |p1, p2|
|
195
235
|
@tangents[ index ] = (p2-p1).norm
|
196
236
|
index += 1
|
197
237
|
}
|
@@ -201,7 +241,7 @@ class Line < Curve
|
|
201
241
|
def length
|
202
242
|
if not @length
|
203
243
|
@length = 0.0
|
204
|
-
|
244
|
+
@points.pairs do |p1, p2|
|
205
245
|
@length += (p1 - p2).r
|
206
246
|
end
|
207
247
|
end
|
@@ -209,54 +249,60 @@ class Line < Curve
|
|
209
249
|
end
|
210
250
|
|
211
251
|
# compute line point at abscissa
|
212
|
-
# Line[ :
|
213
|
-
def point (abscissa)
|
252
|
+
# Line[ :points, [V2D::O, V2D::X] ].point( 0.3 ) => V2D[0.0,0.3]
|
253
|
+
def point (abscissa, container=nil)
|
254
|
+
container ||= V2D[]
|
214
255
|
piece1 = abscissa.to_int
|
215
|
-
if piece1 == @
|
216
|
-
|
256
|
+
if piece1 == @points.size - 1
|
257
|
+
container.xy = @points[-1]
|
258
|
+
else
|
259
|
+
abscissa -= piece1
|
260
|
+
cpoints = @points.slice( piece1, 2 )
|
261
|
+
container.xy = [(cpoints[0].x..cpoints[1].x).sample( abscissa ),
|
262
|
+
(cpoints[0].y..cpoints[1].y).sample( abscissa )]
|
217
263
|
end
|
218
|
-
|
219
|
-
cexts = self.exts.slice( piece1, 2 )
|
220
|
-
return (cexts[0]..cexts[1]).sample( abscissa )
|
264
|
+
return container
|
221
265
|
end
|
222
266
|
|
223
267
|
# compute line frame at abscissa
|
224
268
|
#
|
225
269
|
# for the moment, frame rotation is always 0.0, and scale always 1.0
|
226
270
|
def frame (abscissa)
|
227
|
-
return Frame[ :center, self.point( abscissa ), :vector,
|
271
|
+
return Frame[ :center, self.point( abscissa ), :vector, V2D[ 0.0, 0.0 ], :rotation, 0.0, :scale, 1.0 ]
|
228
272
|
end
|
229
273
|
|
230
274
|
# compute line tangent at abscissa
|
231
|
-
def tangent (abscissa)
|
232
|
-
|
275
|
+
def tangent (abscissa, container=nil)
|
276
|
+
container ||= V2D[]
|
277
|
+
container.xy = @tangents[abscissa.to_int]
|
278
|
+
return container
|
233
279
|
end
|
234
280
|
|
235
281
|
# compute viewbox of the line
|
236
282
|
#
|
237
|
-
# simply call
|
283
|
+
# simply call V2D.viewbox on :points
|
238
284
|
def viewbox
|
239
|
-
return
|
285
|
+
return V2D.viewbox( @points )
|
240
286
|
end
|
241
287
|
|
242
288
|
# translate a line of v offset, v being a vector
|
243
289
|
#
|
244
|
-
# return a new line with every point of :
|
290
|
+
# return a new line with every point of :points translated
|
245
291
|
def translate( v )
|
246
|
-
return Line[ :
|
292
|
+
return Line[ :points, @points.map {|ext| ext.translate( v )} ]
|
247
293
|
end
|
248
294
|
|
249
295
|
# reverse a line
|
250
296
|
#
|
251
|
-
# return a new line with :
|
297
|
+
# return a new line with :points reversed
|
252
298
|
def reverse
|
253
|
-
return Line[ :
|
299
|
+
return Line[ :points, @points.reverse ]
|
254
300
|
end
|
255
301
|
|
256
302
|
# return line svg description
|
257
303
|
def svg
|
258
|
-
path = "M #{
|
259
|
-
|
304
|
+
path = "M #{points[0].x} #{points[0].y} "
|
305
|
+
@points[1..-1].each { |p|
|
260
306
|
path += "L #{p.x} #{p.y}"
|
261
307
|
}
|
262
308
|
return "<path d=\"" + path + "\"/>"
|
@@ -270,12 +316,12 @@ end
|
|
270
316
|
# = Intro
|
271
317
|
# define a circle curve
|
272
318
|
# = Attributes
|
273
|
-
# attribute :center,
|
319
|
+
# attribute :center, V2D[0.0,0.0]
|
274
320
|
# attribute :radius, 1.0
|
275
321
|
# = Example
|
276
|
-
# c = Circle[ :center,
|
322
|
+
# c = Circle[ :center, V2D::O, :radius, 1.0 ] # equiv Circle[]
|
277
323
|
class Circle < Curve
|
278
|
-
attribute :center,
|
324
|
+
attribute :center, V2D[0.0,0.0]
|
279
325
|
attribute :radius, 1.0
|
280
326
|
|
281
327
|
# compute length of the circle
|
@@ -318,10 +364,12 @@ class Circle < Curve
|
|
318
364
|
end
|
319
365
|
|
320
366
|
# compute point at abscissa
|
321
|
-
def point (abscissa)
|
367
|
+
def point (abscissa, container=nil)
|
322
368
|
angle = Range::Angle.sample( abscissa )
|
323
|
-
|
324
|
-
|
369
|
+
container ||=V2D[]
|
370
|
+
container.x = self.cx + self.radius * Math.cos( angle )
|
371
|
+
container.y = self.cy + self.radius * Math.sin( angle )
|
372
|
+
return container
|
325
373
|
end
|
326
374
|
|
327
375
|
# compute tangent at abscissa
|
data/lib/style.rb
CHANGED
@@ -19,27 +19,28 @@ require 'color'
|
|
19
19
|
# render.add( Circle[], Style[ :stroke, Color.red ] )
|
20
20
|
class Style
|
21
21
|
include Attributable
|
22
|
-
attribute :opacity, 1.0
|
22
|
+
# attribute :opacity, 1.0
|
23
23
|
attribute :fill, "none", [String, Color, Gradient]
|
24
|
-
attribute :fillopacity, 1.0
|
24
|
+
# attribute :fillopacity, 1.0
|
25
25
|
attribute :stroke, "none", [String, Color, Gradient]
|
26
26
|
attribute :strokewidth, 1.0
|
27
|
-
attribute :strokeopacity, 1.0
|
27
|
+
# attribute :strokeopacity, 1.0
|
28
28
|
|
29
|
-
def
|
30
|
-
if
|
31
|
-
|
29
|
+
def fillopacity()
|
30
|
+
if @fill.is_a? Color
|
31
|
+
return @fill.a
|
32
32
|
end
|
33
|
-
|
33
|
+
return 1.0
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
if
|
38
|
-
|
36
|
+
def strokeopacity()
|
37
|
+
if @stroke.is_a? Color
|
38
|
+
return @stroke.a
|
39
39
|
end
|
40
|
-
|
40
|
+
return 1.0
|
41
41
|
end
|
42
42
|
|
43
|
+
|
43
44
|
def svgfill
|
44
45
|
if fill.is_a? Color
|
45
46
|
return fill.svg
|
@@ -63,7 +64,7 @@ class Style
|
|
63
64
|
def svgline
|
64
65
|
template = 'style="opacity:%opacity%;fill:%fill%;fill-opacity:%fillopacity%;stroke:%stroke%;stroke-width:%strokewidth%;stroke-opacity:%strokeopacity%"'
|
65
66
|
|
66
|
-
return template.subreplace( {"%opacity%" =>
|
67
|
+
return template.subreplace( {"%opacity%" => 1.0,
|
67
68
|
"%fill%" => svgfill,
|
68
69
|
"%fillopacity%" => fillopacity,
|
69
70
|
"%stroke%" => svgstroke,
|
data/lib/utils.rb
CHANGED
@@ -51,9 +51,10 @@ class Range
|
|
51
51
|
|
52
52
|
# compute the symetric of value in context of range
|
53
53
|
# (0.0..1.0).complement( 0.3 ) => 0.7
|
54
|
+
# (1.0..2.0).complement( 1.3 ) => 1.7
|
54
55
|
def complement( value )
|
55
56
|
diff = value - self.begin
|
56
|
-
return (self.end -
|
57
|
+
return (self.end - diff)
|
57
58
|
end
|
58
59
|
|
59
60
|
|
@@ -317,8 +318,8 @@ class Array
|
|
317
318
|
include Splittable
|
318
319
|
|
319
320
|
# FloatFunctor overloading to synchronize content sampling and splitting
|
320
|
-
def compute( inputs, type )
|
321
|
-
return self.map {|v| v.compute( inputs, type )}.forzip
|
321
|
+
def compute( inputs, type, &block )
|
322
|
+
return self.map {|v| v.compute( inputs, type )}.forzip(nil,&block)
|
322
323
|
end
|
323
324
|
|
324
325
|
end
|
data/lib/xrvg.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Please refer to README for XRVG introduction
|
4
4
|
|
5
5
|
# XRVG version (used in rakefile)
|
6
|
-
XRVG_VERSION = "0.0.
|
6
|
+
XRVG_VERSION = "0.0.2"
|
7
7
|
|
8
8
|
# Standard Ruby extensions
|
9
9
|
require 'enumerator'
|
@@ -26,8 +26,7 @@ require 'color'
|
|
26
26
|
require 'frame'
|
27
27
|
require 'shape'
|
28
28
|
require 'render'
|
29
|
-
|
30
|
-
# require 'bezierspline'
|
29
|
+
require 'bezier'
|
31
30
|
|
32
31
|
# XRVG extensions
|
33
32
|
# require 'bezierbuilders'
|
data/test/test_bezier.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'bezier'
|
3
|
+
|
4
|
+
class BezierTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
@@piece = [ :raw, V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0] ]
|
7
|
+
@@bezier = Bezier.single( *@@piece )
|
8
|
+
@@beziersym = Bezier.raw( V2D[0.0, 0.0], V2D[1.0, 0.0], V2D[0.0, 1.0], V2D[1.0, 1.0] )
|
9
|
+
@@pieces = [[:raw, V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0] ],
|
10
|
+
[:raw, V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0] ]]
|
11
|
+
@@multibezier = Bezier.multi( @@pieces )
|
12
|
+
|
13
|
+
def test_builder
|
14
|
+
b = Bezier.new( :pieces, [BezierSpline[:raw, V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0]]] )
|
15
|
+
assert_equal( V2D[0.0, 1.0], b.firstpoint )
|
16
|
+
|
17
|
+
b = Bezier.single( :raw, V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0] )
|
18
|
+
assert_equal( V2D[0.0, 1.0], b.firstpoint )
|
19
|
+
|
20
|
+
b = Bezier.raw( V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0] )
|
21
|
+
assert_equal( V2D[0.0, 1.0], b.firstpoint )
|
22
|
+
|
23
|
+
b = Bezier.vector( V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0] )
|
24
|
+
assert_equal( V2D[0.0, 1.0], b.firstpoint )
|
25
|
+
|
26
|
+
b = Bezier.multi( [@@piece] )
|
27
|
+
assert_equal( V2D[0.0, 1.0], b.firstpoint )
|
28
|
+
|
29
|
+
b = Bezier.multi( [@@piece,@@piece] )
|
30
|
+
assert_equal( V2D[0.0, 1.0], b.firstpoint )
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_O
|
34
|
+
assert_equal( [V2D::O, V2D::O, V2D::O, V2D::O], Bezier::O.pointlist )
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_piece
|
38
|
+
assert_equal( V2D[0.0, 1.0], @@multibezier.piece( 0 ).firstpoint )
|
39
|
+
assert_equal( V2D[1.0, 0.0], @@multibezier.piece( 1 ).firstpoint )
|
40
|
+
|
41
|
+
assert_equal( V2D[0.0, 1.0], @@multibezier.piece( 0.2 ).firstpoint )
|
42
|
+
assert_equal( V2D[1.0, 0.0], @@multibezier.piece( 0.7 ).firstpoint )
|
43
|
+
|
44
|
+
assert_equal( V2D[0.0, 1.0], @@multibezier.piece( 0.2, :parameter ).firstpoint )
|
45
|
+
assert_equal( V2D[0.0, 1.0], @@multibezier.piece( 0.7, :parameter ).firstpoint )
|
46
|
+
assert_equal( V2D[1.0, 0.0], @@multibezier.piece( 1.2, :parameter ).firstpoint )
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_piecenumber
|
50
|
+
assert_equal( 1, @@bezier.piecenumber )
|
51
|
+
assert_equal( 2, @@multibezier.piecenumber )
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_viewbox
|
55
|
+
assert_equal( [0.0, 0.0, 1.0, 1.0], @@bezier.viewbox )
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_pointlist
|
59
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0],
|
60
|
+
V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0] ], @@multibezier.pointlist() )
|
61
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0],
|
62
|
+
V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0] ], @@multibezier.pointlist(:raw) )
|
63
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 0.0], V2D[1.0, 0.0], V2D[-1.0, 0.0],
|
64
|
+
V2D[1.0, 0.0], V2D[1.0, 2.0], V2D[2.0, 0.0], V2D[-1.0, 1.0] ], @@multibezier.pointlist(:vector) )
|
65
|
+
|
66
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0]], @@multibezier.piece(0).pointlist() )
|
67
|
+
assert_equal( [ V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0]], @@multibezier.piece(1).pointlist() )
|
68
|
+
|
69
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0]], @@multibezier.piece(0).pointlist(:raw) )
|
70
|
+
assert_equal( [ V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0]], @@multibezier.piece(1).pointlist(:raw) )
|
71
|
+
|
72
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 0.0], V2D[1.0, 0.0], V2D[-1.0, 0.0]], @@multibezier.piece(0).pointlist(:vector) )
|
73
|
+
assert_equal( [ V2D[1.0, 0.0], V2D[1.0, 2.0], V2D[2.0, 0.0], V2D[-1.0, 1.0]], @@multibezier.piece(1).pointlist(:vector) )
|
74
|
+
|
75
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0]], @@multibezier.piece(0.2).pointlist(:raw) )
|
76
|
+
assert_equal( [ V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0]], @@multibezier.piece(0.8).pointlist(:raw) )
|
77
|
+
|
78
|
+
assert_equal( [ V2D[0.0, 1.0], V2D[1.0, 1.0], V2D[0.0, 0.0], V2D[1.0, 0.0]], @@multibezier.piece(0.2, :parameter).pointlist )
|
79
|
+
assert_equal( [ V2D[1.0, 0.0], V2D[2.0, 2.0], V2D[1.0, 1.0], V2D[2.0, 0.0]], @@multibezier.piece(1.2, :parameter).pointlist )
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_firstpoint
|
83
|
+
assert_equal( V2D[0.0, 1.0], @@multibezier.firstpoint )
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_lastpoint
|
87
|
+
assert_equal( V2D[2.0, 0.0], @@multibezier.lastpoint )
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_beziers
|
91
|
+
beziers = @@multibezier.beziers
|
92
|
+
assert_equal( 2, beziers.length )
|
93
|
+
assert_equal( V2D[0.0, 1.0], beziers[0].firstpoint )
|
94
|
+
assert_equal( V2D[1.0, 0.0], beziers[1].firstpoint )
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def test_computelength
|
99
|
+
assert( (1.0 - Bezier.raw( V2D[0.0, 0.0], V2D[1.0, 0.0], V2D[0.0, 0.0], V2D[1.0, 0.0] ).length()).abs < 0.00001 )
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def test_point
|
104
|
+
assert( V2D.vequal?( V2D[0.5, 0.5], @@beziersym.point( 0.5 ) ) )
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
def test_point_boundary
|
109
|
+
assert( V2D.vequal?( @@beziersym.point( 0.0 ), @@beziersym.point( -1.0 ) ) )
|
110
|
+
assert( V2D.vequal?( @@beziersym.point( 1.0 ), @@beziersym.point( 2.0 ) ) )
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_parameter
|
114
|
+
assert( V2D.vequal?( @@beziersym.piece(0).point( 0.1 ), @@beziersym.point( 0.1, nil, :parameter ) ) )
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_tangent
|
118
|
+
assert( V2D.vequal?( V2D[0.0, 0.5], @@beziersym.tangent( 0.5 ) ) )
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_acc
|
122
|
+
assert( V2D.vequal?( V2D[0.0, 0.0], @@beziersym.acc( 0.5 ) ) )
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_point2
|
126
|
+
container = V2D[0.0,0.0]
|
127
|
+
assert( V2D.vequal?( V2D[0.5, 0.5], @@beziersym.point( 0.5, container ) ) )
|
128
|
+
assert( V2D.vequal?( V2D[0.5, 0.5], container ) )
|
129
|
+
end
|
130
|
+
|
131
|
+
def test_tangent2
|
132
|
+
container = V2D[0.0,0.0]
|
133
|
+
assert( V2D.vequal?( V2D[0.0, 0.5], @@beziersym.tangent( 0.5, container ) ) )
|
134
|
+
assert( V2D.vequal?( V2D[0.0, 0.5], container ) )
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_tangent3
|
138
|
+
container = V2D[0.0,0.0]
|
139
|
+
assert( V2D.vequal?( V2D[0.0, 0.0], @@beziersym.acc( 0.5, container ) ) )
|
140
|
+
assert( V2D.vequal?( V2D[0.0, 0.0], container ) )
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_ranges
|
144
|
+
assert_equal( [(0.0..1.0), (1.0..2.0)], @@multibezier.ranges )
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
|
151
|
+
|