prevent double call of _cleanup, which harms usefiles (and is a bad idea in general)
[PyX.git] / test / functional / test_deformer.py
blob61b367aa7a427b534d583da9500ab4bc30008c9d
1 #!/usr/bin/env python
2 import sys; sys.path[:0] = ["../.."]
3 import warnings, math
4 from pyx import *
5 from pyx.deformer import *
6 from pyx import normpath
8 ##### helpers ##############################################################
10 def bboxrect(cmd):
11 return cmd.bbox().enlarged(5*unit.t_mm).rect()
13 def dotest(c, x, y, test):
14 c2 = c.insert(canvas.canvas([trafo.translate(x, y)]))
15 eval("%s(c2)" % test)
16 c.stroke(bboxrect(c2))
18 def drawpathwbbox(c, p):
19 c.stroke(p, [color.rgb.red])
20 np = p.normpath()
21 c.stroke(np, [color.rgb.green, style.linestyle.dashed])
22 c.stroke(bboxrect(p))
24 ##### tests ################################################################
26 def testcycloid(c):
28 # dependence on turnangle
29 p = path.line(0, 0, 3, 0)
30 c.stroke(p, [style.linewidth.THIN])
31 cyc = cycloid(halfloops=3, skipfirst=0.5, skiplast=0.5, curvesperhloop=2)
32 c.stroke(p, [cyc(turnangle=00)])
33 c.stroke(p, [cyc(turnangle=22), color.rgb.red])
34 c.stroke(p, [cyc(turnangle=45), color.rgb.green])
35 c.stroke(p, [cyc(turnangle=67), color.rgb.blue])
36 c.stroke(p, [cyc(turnangle=90), color.cmyk.Cyan])
38 # dependence on curvesperloop
39 p = path.curve(5, 0, 8, 0, 6, 4, 9, 4)
40 c.stroke(p)
41 cyc = cycloid(halfloops=16, skipfirst=0, skiplast=0, curvesperhloop=1)
42 c.stroke(p, [cyc(curvesperhloop=2)])
43 c.stroke(p, [cyc(curvesperhloop=3), color.rgb.red])
44 c.stroke(p, [cyc(curvesperhloop=4), color.rgb.green])
45 c.stroke(p, [cyc(curvesperhloop=10), color.rgb.blue])
47 # extremely curved path
48 p = path.curve(0,2, 0.5,5, 1,6, 2,2)
49 c.stroke(p)
50 cyc = cycloid(radius=0.7, halfloops=7, skipfirst=0, skiplast=0, curvesperhloop=1)
51 c.stroke(p, [cyc(curvesperhloop=2)])
52 c.stroke(p, [cyc(curvesperhloop=3), color.rgb.red])
53 c.stroke(p, [cyc(curvesperhloop=4), color.rgb.green])
54 c.stroke(p, [cyc(curvesperhloop=50), color.rgb.blue])
57 def testcornersmoothed(c):
58 p = path.path(
59 path.moveto(0,0),
60 path.lineto(3,0),
61 path.lineto(5,7),
62 path.curveto(0,10, -2,8, 0,6),
63 path.lineto(0,4),
64 # horrible overshooting with obeycurv=1
65 #path.lineto(-4,4), path.curveto(-7,5, -4,2, -5,2),
66 path.lineto(-4,3), path.curveto(-7,5, -4,2, -5,2),
67 #path.arct(-6,4, -5,1, 1.5),
68 #path.arc(-5, 3, 0.5, 0, 180),
69 path.lineto(-5,1),
70 path.lineto(-0.2,0.2),
71 path.closepath()
72 ) + path.circle(0,1,2)
74 c.stroke(p, [color.gray(0.8), style.linewidth.THICk])
75 c.stroke(p.normpath(), [color.gray(0.8), style.linewidth.THICk])
76 c.stroke(p, [cornersmoothed(radius=0.85, softness=1, obeycurv=1), style.linewidth.Thin])
77 c.stroke(p, [cornersmoothed(radius=0.85, softness=1, obeycurv=0), color.rgb.red])
78 c.stroke(p, [cornersmoothed(radius=0.20, softness=1, obeycurv=0), color.rgb.green])
79 c.stroke(p, [cornersmoothed(radius=1.20, softness=1, obeycurv=0), color.rgb.blue])
81 p = path.path(
82 path.moveto(0,10),
83 path.curveto(1,10, 4,12, 2,11),
84 path.curveto(4,8, 4,12, 0,11)
86 c.stroke(p, [color.gray(0.8), style.linewidth.THICk])
87 c.stroke(p.normpath(), [color.gray(0.8), style.linewidth.THICk])
88 c.stroke(p, [cornersmoothed(radius=0.85, softness=1, obeycurv=1), style.linewidth.Thick])
89 c.stroke(p, [cornersmoothed(radius=0.85, softness=1, obeycurv=0), color.rgb.red])
90 c.stroke(p, [cornersmoothed(radius=0.20, softness=1, obeycurv=0), color.rgb.green])
91 c.stroke(p, [cornersmoothed(radius=1.20, softness=1, obeycurv=0), color.rgb.blue])
94 def hard_test(c, pth, dist, pardef, move=(0, 0), label=None, dotests=[True]*4, checklens=[None]*4):
95 print("hard test of parallel: ", label)
96 tr = trafo.translate(*move)
97 if label is not None:
98 c.text(0.5*(pth.bbox().left() + pth.bbox().right()),
99 0.5*(pth.bbox().bottom() + pth.bbox().top()), label, [tr])
100 c.stroke(pth, [tr])
101 pth_rev = pth.reversed()
102 dists = [dist, -dist, -dist, dist]
103 paths = [pth, pth_rev, pth, pth_rev]
104 styles = [[color.rgb.red], [style.linestyle.dashed], [color.rgb.blue], [color.rgb.green, style.linestyle.dashed]]
105 for i, d, p, dotest, assertlens, st in zip(range(4), dists, paths, dotests, checklens, styles):
106 if dotest:
107 pl = pardef(distance=d).deform(p)
108 c.stroke(pl, st + [tr])#, deco.shownormpath()])
109 if assertlens is None:
110 print([len(nsp) for nsp in pl])
111 else:
112 if len(pl) != len(assertlens):
113 print("WARNING: wrong number of nsp (%d instead of expected %d) in test %d" % (len(pl), len(assertlens), i))
114 for j, (n_nspitems, nsp) in enumerate(zip(assertlens, pl)):
115 if len(nsp) != n_nspitems:
116 print("WARNING: wrong number of nsp items (%d instead of expected %d) in test %d, nsp number %d" % (len(nsp), n_nspitems, i, j))
118 def testparallel_1(c):
120 # HARD TESTS of elementary geometry:
122 # test for correct skipping of short ugly pieces:
123 move = (-2, 0)
124 p = path.path(path.moveto(0, 1), path.lineto(10, 0.3), path.lineto(12, 0), path.lineto(0, 0))
125 p.append(path.closepath())
126 hard_test(c, p, 0.1, parallel(0.0), move, "A", checklens=[[15],[15],[4],[4]])
127 hard_test(c, p, 0.25, parallel(0.0, sharpoutercorners=True), move, "A", checklens=[[12],[12],[3],[3]])
128 hard_test(c, p, 0.55, parallel(0.0), move, "A", checklens=[[15],[15],[],[]])
130 # test non-intersecting/too short neighbouring pathels
131 move = (0, 4)
132 p = path.curve(0,0, 0,1, 1,2, 2,0)
133 p.append(path.lineto(2.1, 0.1))
134 p.append(path.lineto(1.6, -2))
135 p.append(path.lineto(2.1, -2))
136 p.append(path.lineto(-0.15, 0))
137 p.append(path.closepath())
138 hard_test(c, p, 0.02, parallel(0.0, sharpoutercorners=1), move, "B", checklens=[[3],[3],[11],[11]])
139 hard_test(c, p, 0.06, parallel(0.0), move, "B", checklens=[[3],[3],[10],[9]]) # difference is due to rounding in path._arctobeziers
140 hard_test(c, p, 0.3, parallel(0.0), move, "B", checklens=[[25],[25],[5],[5]])
141 hard_test(c, p, 0.3, parallel(0.0, sharpoutercorners=1), move, "B", checklens=[[22],[22],[5],[5]])
143 # test extreme precision:
144 move = (3.5, 2)
145 p = path.curve(0,0, 0,1, 1,1, 1,0)
146 p.append(path.closepath())
147 hard_test(c, p, 0.1, parallel(0.0), move, "C", checklens=[[8],[8],[2],[2]])
148 hard_test(c, p, 0.1, parallel(0.0, relerr=1e-15, checkdistanceparams=[0.5]), move, "C", checklens=[[23],[23],[15],[15]])
150 # test for numeric instabilities:
151 move = (6, 2)
152 p = path.curve(0,0, 1,1, 1,1, 2,0)
153 p.append(path.closepath())
154 hard_test(c, p, 0.1, parallel(0.0, relerr=0.15, checkdistanceparams=[0.5]), move, "D", checklens=[[11],[11],[3],[3]])
155 hard_test(c, p, 0.3, parallel(0.0), move, "D", checklens=[[11],[11],[3],[3]])
157 # test for an empty parallel path:
158 move = (5, 5)
159 p = path.circle(0, 0, 0.5).normpath()
160 nspitems = [nspitem for nspitem in p[0] if isinstance(nspitem, normpath.normcurve_pt)]
161 nspitems[-1] = nspitems[-1].modifiedend_pt(*nspitems[0].atbegin_pt())
162 p = normpath.normpath([normpath.normsubpath(nspitems, closed=True)])
163 hard_test(c, p, 0.55, parallel(0.0), move, "E", checklens=[[],[],[9],[9]])
164 hard_test(c, p, 0.4999, parallel(0.0, relerr=1.0e-15), move, "E", checklens=[[1,14,8],[1,14],[17],[17]])
166 # a degenerate path:
167 move = (13, 3)
168 p = path.curve(0,0, 0,-5, 0,1, 0,0.5)
169 hard_test(c, p, 0.10, parallel(0.0, dointersection=False), move, "F", dotests=[True,True,False,False], checklens=[[13],[12],[13],[12]])
170 hard_test(c, p, 0.13, parallel(0.0, dointersection=False), move, "F", dotests=[False,False,True,True], checklens=[[13],[12],[13],[12]])
172 # test for too big curvatures in the middle:
173 move = (9, 2.5)
174 p = path.curve(0,0, 1,1, 1,1, 2,0)
175 hard_test(c, p, 0.4, parallel(0.0, relerr=1.0e-2), move, "G", checklens=[[2],[2],[4],[4]])
176 hard_test(c, p, 0.6, parallel(0.0, relerr=1.0e-2), move, "G", checklens=[[2],[2],[4],[4]])
177 hard_test(c, p, 0.8, parallel(0.0, relerr=1.0e-2), move, "G", checklens=[[2],[2],[4],[4]])
178 hard_test(c, p, 1.7, parallel(0.0, relerr=1.0e-2), move, "G", checklens=[[2],[2],[1,1],[1,1]])
180 # deformation of the deformation:
181 move = (11, 6)
182 p = path.curve(-1,0, 0,1, 0,1, 1,0).normpath()
183 c.stroke(p, [trafo.translate(*move), color.gray(0.8)])
184 dist = unit.u_pt/p.curvature_pt([normpath.normpathparam(p,0,0.5)])[0]
185 p = parallel(dist, relerr=1.0e-2, dointersection=0).deform(p)
186 assert len(p) == 2
187 assert len(p[0]) == len(p[1]) == 2
188 c.stroke(p, [trafo.translate(*move), color.gray(0.8)])
189 hard_test(c, p, -dist, parallel(0.0), move, "H", checklens=[[4],[4],[2],[2]])
191 # test for infinite curvature in the middle:
192 move = (11, 8.5)
193 p = path.curve(0,0, 1,1, 0,1, 1,0).normpath()
194 hard_test(c, p, 0.2, parallel(0.0), move, "I", checklens=[[1,1],[1,1],[2],[2]])
195 hard_test(c, p, 1.5, parallel(0.0), move, "I", checklens=[[1,1],[1,1],[7],[7]])
196 #ard_test(c, p, 5.0, parallel(0.0), move, "I", checklens=[[],[],[7],[7]])
198 # test for infinite curvature at the end:
199 move = (-2, 13)
200 p = path.curve(0,0, 0.5,0.5, 0.75,0.5, 0.75,0.5)
201 hard_test(c, p, 0.1, parallel(0.0, relerr=1.0e-4), move, "J", checklens=[[5],[5],[5],[5]])
202 # test for infinite curvature when the path goes on
203 # XXX this is not correctly detected if rlineto(1,0). Expect two nsp
204 p.append(path.rlineto(0, 1))
205 hard_test(c, p, 0.22, parallel(0.0, relerr=1.0e-4), move, "J", checklens=[[4],[4],[3,1],[1,3]])
207 # test for too big curvature in the middle, the non-intersecting case
208 move = (0, 8)
209 p = path.curve(-1,-1, 4,4, -4,4, 1,-1).normpath()
210 dist = unit.u_pt * (1.0/p.curvature_pt([normpath.normpathparam(p, 0, 0.5)])[0])
211 hard_test(c, p, 1.5*dist, parallel(0.0, dointersection=False), move, "K", checklens=[[1,1],[1,1],[2],[2]])
212 hard_test(c, p, dist+normpath._epsilon, parallel(0.0, dointersection=False, relerr=1.0e-5), move, "K", checklens=[[11,11],[11,11],[16],[16]])
213 hard_test(c, p, dist+0*normpath._epsilon, parallel(0.0, dointersection=False, relerr=1.0e-5), move, "K", checklens=[[22],[22],[16],[16]])
215 # what is to be done with the arcs running around corners?
216 # for dist=1.1 they do not even intersect with the original path:
217 # TODO
218 move = (8, 14)
219 p = path.rect(0, 0, 1, 1).normpath()
220 hard_test(c, p, 1.1, parallel(0.0), move, "L", dotests=[True,True,False,False], checklens=[[20],[20],None,None])
221 hard_test(c, p, 0.55, parallel(0.0), move, "L", dotests=[True,True,False,False], checklens=[[28],[28],None,None])
223 # very small lines approximating a curve
224 # make sure that there is no "dust" remaining from the many intersections
225 move = (3, 9)
226 N = 12
227 angle = 0.5*math.pi / (N-1.0)
228 p = path.path(path.moveto(0, 0))
229 for n in range(N):
230 p.append(path.lineto(2+math.sin(n*angle), 1-math.cos(n*angle)))
231 p.append(path.rlineto(0, 1))
232 p.append(path.rlineto(2, 0))
233 p.append(path.rlineto(0, -2))
234 p = p.transformed(trafo.translate(0, 0.05))
235 p = p << p.transformed(trafo.scale(1, -1)).reversed()
236 hard_test(c, p, 0.6, parallel(0.0), move, "M", checklens=[[43],[43],[29],[29]])
238 # intersections where paths are parallel (in the middle of a nsp-item)
239 move = (4, 15)
240 c.text(move[0], move[1]+0.2, "N")
241 tr = trafo.translate(*move)
242 par = parallel(0.1)
243 par.dist_pt = unit.topt(par.distance)
244 c1 = path.curve(-2,-1, -2,1, 2,-1, 2,1).transformed(tr).normpath()
245 c2 = path.curve(-2,-1, -2,1/3.0, 2,1/3.0, 2,-1).transformed(tr).normpath()
246 l = path.line(-2,0, 2,0).transformed(tr).normpath()
247 for p in [c1, c2, l]:
248 c.stroke(p)
249 p = (c1 + l).normpath()
250 try:
251 par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
252 except IntersectionError as e:
253 assert str(e) == "Cannot determine whether curves intersect (parallel and equally curved)"
254 p = c2 + l
255 assert par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
256 p = c2 + l.reversed()
257 assert par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
258 p = c2.reversed() + l
259 assert not par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
260 p = c2.reversed() + l.reversed()
261 assert not par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
262 p = c1 + c2
263 assert not par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
264 p = c2 + c1
265 assert par._can_continue(mynormpathparam(p,0,0,0.5), mynormpathparam(p,1,0,0.5))
266 # intersections where paths are parallel (between nsp-items)
267 c11, c12 = c1.split([normpath.normpathparam(c1, 0, 0.5)])
268 c21, c22 = c2.split([normpath.normpathparam(c2, 0, 0.5)])
269 l1, l2 = l.split([normpath.normpathparam(l, 0, 0.5)])
270 p = (c21 << l2 + l1 << c22).normpath() # curve-line + line-curve
271 assert par._can_continue(mynormpathparam(p,1,0,1), mynormpathparam(p,0,1,0)) # line -> line
272 assert not par._can_continue(mynormpathparam(p,0,0,1), mynormpathparam(p,1,1,0)) # curve -> curve
274 # intersections where paths are parallel (in the middle of a nsp-item)
275 move = (12, 13)
276 p1 = path.path(path.moveto(0,0), path.curveto(0,3, 1,5, 1,0)).normpath()
277 params1, params2 = p1.intersect(path.line(0.5,-1, 0.5,5))
278 p11, p12 = p1.split(params1)
279 p11.append(path.rlineto(0,-2))
280 p = p11 << p12
281 p.append(path.closepath())
282 hard_test(c, p, 0.55, parallel(0.0), move, "O", dotests=[True,True,False,False], checklens=[[10],[10],None,None])
284 # jump to too large curvature between nspitems
285 move = (-2, 17)
286 p = path.path(path.moveto(0,0), path.arc(2,0.5,0.5,-90,90), path.lineto(0,1)).normpath()
287 hard_test(c, p, 0.55, parallel(0.0), move, "P", dotests=[True,True,True,True], checklens=[[1,1],[1,1],[7],[7]])
289 def testparallel_2(c):
291 # a case with several dangers:
292 # - double intersection pairs
293 # - intersections with angle 0
294 # - inner intersections that have to be cut away by _between_paths
295 move = (10, 2)
296 nsp = normpath.normsubpath([# <<<
297 #ormpath.normline_pt(-87.5005, 184.037, -86.2747, 184.198),
298 #ormpath.normline_pt(-86.2747, 184.198, -85.0394, 184.252),
299 #ormpath.normline_pt(-85.0394, 184.252, -83.8041, 184.198),
300 #ormpath.normline_pt(-83.8041, 184.198, -82.5782, 184.037),
301 #ormpath.normline_pt(-82.5782, 184.037, -81.3711, 183.769),
302 #ormpath.normline_pt(-81.3711, 183.769, -80.1918, 183.397),
303 #ormpath.normline_pt(-80.1918, 183.397, -79.0495, 182.924),
304 #ormpath.normline_pt(-79.0495, 182.924, -77.9528, 182.353),
305 #ormpath.normline_pt(-77.9528, 182.353, -76.9099, 181.689),
306 #ormpath.normline_pt(-76.9099, 181.689, -75.929, 180.936),
307 #ormpath.normline_pt(-75.929, 180.936, -75.0174, 180.101),
308 #ormpath.normline_pt(-75.0174, 180.101, -74.1821, 179.189),
309 #ormpath.normline_pt(-74.1821, 179.189, -73.4293, 178.208),
310 #ormpath.normline_pt(-73.4293, 178.208, -72.765, 177.165),
311 #ormpath.normline_pt(-72.765, 177.165, -72.1941, 176.069),
312 #ormpath.normline_pt(-72.1941, 176.069, -71.7209, 174.926),
313 #ormpath.normline_pt(-71.7209, 174.926, -71.3491, 173.747),
314 #ormpath.normline_pt(-71.3491, 173.747, -71.0815, 172.54),
315 #ormpath.normline_pt(-71.0815, 172.54, -70.9201, 171.314),
316 #ormpath.normline_pt(-70.9201, 171.314, -70.8661, 170.079),
317 #ormpath.normline_pt(-70.8661, 170.079, -70.9201, 168.843),
318 #ormpath.normline_pt(-70.9201, 168.843, -71.0815, 167.618),
319 #ormpath.normline_pt(-71.0815, 167.618, -71.3491, 166.41),
320 #ormpath.normline_pt(-71.3491, 166.41, -71.7209, 165.231),
321 #ormpath.normline_pt(-71.7209, 165.231, -72.1941, 164.089),
322 #ormpath.normline_pt(-72.1941, 164.089, -72.765, 162.992),
323 #ormpath.normline_pt(-72.765, 162.992, -73.4293, 161.949),
324 #ormpath.normline_pt(-73.4293, 161.949, -74.1821, 160.968),
325 #ormpath.normline_pt(-74.1821, 160.968, -75.0174, 160.057),
326 #ormpath.normline_pt(-75.0174, 160.057, -75.929, 159.221),
327 #ormpath.normline_pt(-75.929, 159.221, -76.9099, 158.469),
328 #ormpath.normline_pt(-76.9099, 158.469, -77.9528, 157.804),
329 #ormpath.normline_pt(-77.9528, 157.804, -77.9528, -28.3465),
330 #ormpath.normline_pt(-77.9528, -28.3465, -77.9797, -28.9641),
331 #ormpath.normline_pt(-77.9797, -28.9641, -78.0604, -29.577),
332 #ormpath.normline_pt(-78.0604, -29.577, -78.1942, -30.1806),
333 #ormpath.normline_pt(-78.1942, -30.1806, -78.3801, -30.7702),
334 #ormpath.normline_pt(-78.3801, -30.7702, -78.6167, -31.3414),
335 #ormpath.normline_pt(-78.6167, -31.3414, -78.9022, -31.8897),
336 #ormpath.normline_pt(-78.9022, -31.8897, -79.2344, -32.4111),
337 #ormpath.normline_pt(-79.2344, -32.4111, -79.6107, -32.9016),
338 #ormpath.normline_pt(-79.6107, -32.9016, -80.0284, -33.3574),
339 #ormpath.normline_pt(-80.0284, -33.3574, -80.4842, -33.7751),
340 #ormpath.normline_pt(-80.4842, -33.7751, -80.9747, -34.1514),
341 #ormpath.normline_pt(-80.9747, -34.1514, -81.4961, -34.4836),
342 #ormpath.normline_pt(-81.4961, -34.4836, -82.0444, -34.7691),
343 #ormpath.normline_pt(-82.0444, -34.7691, -82.6156, -35.0057),
344 #ormpath.normline_pt(-82.6156, -35.0057, -83.2052, -35.1916),
345 #ormpath.normline_pt(-83.2052, -35.1916, -83.8088, -35.3254),
346 #ormpath.normline_pt(-83.8088, -35.3254, -84.3307, -35.3941),
347 #ormpath.normline_pt(-84.3307, -35.3941, -84.3307, -169.37),
348 #ormpath.normline_pt(-84.3307, -169.37, -28.423, -169.37),
349 #ormpath.normline_pt(-28.423, -169.37, 0, -156.252),
350 #ormpath.normline_pt(0, -156.252, 0, -157.813),
351 #ormpath.normline_pt(0, -157.813, -28.1117, -170.787),
352 #ormpath.normline_pt(-28.1117, -170.787, -150, -170.787),
353 normpath.normline_pt(-150, -170.787, -361.417, -170.787), # start
354 normpath.normline_pt(-361.417, -170.787, -361.417, -169.37),
355 normpath.normline_pt(-361.417, -169.37, -299.055, -169.37),
356 normpath.normline_pt(-299.055, -169.37, -299.055, -141.732),
357 normpath.normline_pt(-299.055, -141.732, -297.638, -141.732),
358 normpath.normline_pt(-297.638, -141.732, -297.638, -143.15),
359 normpath.normline_pt(-297.638, -143.15, -297.638, -169.37),
360 normpath.normline_pt(-297.638, -169.37, -270.709, -169.37),
361 normpath.normline_pt(-270.709, -169.37, -270.709, -143.15),
362 normpath.normline_pt(-270.709, -143.15, -297.638, -143.15),
363 normpath.normline_pt(-297.638, -143.15, -297.638, -141.732),
364 normpath.normline_pt(-297.638, -141.732, -284.882, -141.732),
365 normpath.normline_pt(-284.882, -141.732, -284.882, -113.386),
366 normpath.normline_pt(-284.882, -113.386, -283.465, -113.386),
367 normpath.normline_pt(-283.465, -113.386, -283.465, -114.803),
368 normpath.normline_pt(-283.465, -114.803, -283.465, -141.732),
369 normpath.normline_pt(-283.465, -141.732, -269.291, -141.732),
370 normpath.normline_pt(-269.291, -141.732, -269.291, -169.37),
371 normpath.normline_pt(-269.291, -169.37, -242.362, -169.37),
372 normpath.normline_pt(-242.362, -169.37, -242.362, -141.732),
373 normpath.normline_pt(-242.362, -141.732, -240.945, -141.732),
374 normpath.normline_pt(-240.945, -141.732, -240.945, -143.15),
375 normpath.normline_pt(-240.945, -143.15, -240.945, -169.37),
376 normpath.normline_pt(-240.945, -169.37, -214.016, -169.37),
377 normpath.normline_pt(-214.016, -169.37, -214.016, -143.15),
378 normpath.normline_pt(-214.016, -143.15, -240.945, -143.15),
379 normpath.normline_pt(-240.945, -143.15, -240.945, -141.732),
380 normpath.normline_pt(-240.945, -141.732, -228.189, -141.732),
381 normpath.normline_pt(-228.189, -141.732, -228.189, -114.803),
382 normpath.normline_pt(-228.189, -114.803, -283.465, -114.803),
383 normpath.normline_pt(-283.465, -114.803, -283.465, -113.386),
384 normpath.normline_pt(-283.465, -113.386, -226.772, -113.386),
385 normpath.normline_pt(-226.772, -113.386, -226.772, -141.732),
386 normpath.normline_pt(-226.772, -141.732, -212.598, -141.732),
387 normpath.normline_pt(-212.598, -141.732, -212.598, -169.37),
388 normpath.normline_pt(-212.598, -169.37, -150, -169.37), # end
389 #ormpath.normline_pt(-150, -169.37, -85.748, -169.37),
390 #ormpath.normline_pt(-85.748, -169.37, -85.748, -35.3941),
391 #ormpath.normline_pt(-85.748, -35.3941, -86.2699, -35.3254),
392 #ormpath.normline_pt(-86.2699, -35.3254, -86.8735, -35.1916),
393 #ormpath.normline_pt(-86.8735, -35.1916, -87.4631, -35.0057),
394 #ormpath.normline_pt(-87.4631, -35.0057, -88.0343, -34.7691),
395 #ormpath.normline_pt(-88.0343, -34.7691, -88.5827, -34.4836),
396 #ormpath.normline_pt(-88.5827, -34.4836, -89.1041, -34.1514),
397 #ormpath.normline_pt(-89.1041, -34.1514, -89.5946, -33.7751),
398 #ormpath.normline_pt(-89.5946, -33.7751, -90.0504, -33.3574),
399 #ormpath.normline_pt(-90.0504, -33.3574, -90.468, -32.9016),
400 #ormpath.normline_pt(-90.468, -32.9016, -90.8444, -32.4111),
401 #ormpath.normline_pt(-90.8444, -32.4111, -91.1765, -31.8897),
402 #ormpath.normline_pt(-91.1765, -31.8897, -91.462, -31.3414),
403 #ormpath.normline_pt(-91.462, -31.3414, -91.6986, -30.7702),
404 #ormpath.normline_pt(-91.6986, -30.7702, -91.8845, -30.1806),
405 #ormpath.normline_pt(-91.8845, -30.1806, -92.0183, -29.577),
406 #ormpath.normline_pt(-92.0183, -29.577, -92.099, -28.9641),
407 #ormpath.normline_pt(-92.099, -28.9641, -92.126, -28.3465),
408 #ormpath.normline_pt(-92.126, -28.3465, -92.126, 157.804),
409 #ormpath.normline_pt(-92.126, 157.804, -93.1688, 158.469),
410 #ormpath.normline_pt(-93.1688, 158.469, -94.1498, 159.221),
411 #ormpath.normline_pt(-94.1498, 159.221, -95.0613, 160.057),
412 #ormpath.normline_pt(-95.0613, 160.057, -95.8967, 160.968),
413 #ormpath.normline_pt(-95.8967, 160.968, -96.6494, 161.949),
414 #ormpath.normline_pt(-96.6494, 161.949, -97.3138, 162.992),
415 #ormpath.normline_pt(-97.3138, 162.992, -97.8847, 164.089),
416 #ormpath.normline_pt(-97.8847, 164.089, -98.3578, 165.231),
417 #ormpath.normline_pt(-98.3578, 165.231, -98.7297, 166.41),
418 #ormpath.normline_pt(-98.7297, 166.41, -98.9973, 167.618),
419 #ormpath.normline_pt(-98.9973, 167.618, -99.1587, 168.843),
420 #ormpath.normline_pt(-99.1587, 168.843, -99.2126, 170.079),
421 #ormpath.normline_pt(-99.2126, 170.079, -99.1587, 171.314),
422 #ormpath.normline_pt(-99.1587, 171.314, -98.9973, 172.54),
423 #ormpath.normline_pt(-98.9973, 172.54, -98.7297, 173.747),
424 #ormpath.normline_pt(-98.7297, 173.747, -98.3578, 174.926),
425 #ormpath.normline_pt(-98.3578, 174.926, -97.8847, 176.069),
426 #ormpath.normline_pt(-97.8847, 176.069, -97.3138, 177.165),
427 #ormpath.normline_pt(-97.3138, 177.165, -96.6494, 178.208),
428 #ormpath.normline_pt(-96.6494, 178.208, -95.8967, 179.189),
429 #ormpath.normline_pt(-95.8967, 179.189, -95.0613, 180.101),
430 #ormpath.normline_pt(-95.0613, 180.101, -94.1498, 180.936),
431 #ormpath.normline_pt(-94.1498, 180.936, -93.1688, 181.689),
432 #ormpath.normline_pt(-93.1688, 181.689, -92.126, 182.353),
433 #ormpath.normline_pt(-92.126, 182.353, -91.0292, 182.924),
434 #ormpath.normline_pt(-91.0292, 182.924, -89.8869, 183.397),
435 #ormpath.normline_pt(-89.8869, 183.397, -88.7077, 183.769),
436 #ormpath.normline_pt(-88.7077, 183.769, -87.5005, 184.037),
437 ], closed=1) # >>>
438 p = normpath.normpath([nsp])
439 c.stroke(p, [trafo.translate(*move)])
440 hard_test(c, p, 0.47504345 - 5*normpath._epsilon, parallel(0.0), move, "Y", checklens=[[37,14],[37,14],[7,7],[7,7]])
441 hard_test(c, p, 0.47504345 + 5*normpath._epsilon, parallel(0.0), move, "Y", checklens=[[37,7],[37,7],[7,7,7],[7,7,7]])
442 hard_test(c, p, 0.5, parallel(0.0), move, "Y", checklens=[[36,7],[36,7],[6,5,6,3,7,3],[6,3,7,3,5,6]])
443 hard_test(c, p, 0.6125, parallel(0.0), move, "Y", checklens=[[35],[35],[3],[3]])
444 hard_test(c, p, 0.6130, parallel(0.0), move, "Y", checklens=[[35],[35],[],[]])
446 # a path of two subpaths:
447 # and with inner intersections to be cut away by _between_paths
448 move = (0, 0)
449 p = path.circle(-6, 0, 2)
450 p += path.path(path.moveto(0,0), path.curveto(0,16, -11,5, 5,5))
451 p += path.path(path.lineto(5,4), path.lineto(7,4), path.lineto(7,6), path.lineto(4,6),
452 path.lineto(4,7), path.lineto(5,7), path.lineto(3,1), path.closepath())
453 p = p.transformed(trafo.scale(0.5)).normpath()
454 hard_test(c, p, 0.05, parallel(0.0), move, "Z", checklens=[[10,2,8],[9,2,10],[13,4,4],[13,4,4]])
455 hard_test(c, p, 0.3, parallel(0.0), move, "Z", checklens=[[10,4,5],[4,6,10],[13,4],[13,4]])
456 hard_test(c, p, 0.6, parallel(0.0), move, "Z", checklens=[[],[],[13,4],[13,4]])
459 def testlinesmoothed(c):
461 # dependence on turnangle
462 p = path.path(path.moveto(0, 0), path.lineto(1, 0), path.lineto(2, 1), path.lineto(4, -1),
463 path.lineto(5, 0), path.lineto(6, 0))
464 c.stroke(p)
465 d = linesmoothed()
466 c.stroke(p, [d])
467 c.stroke(p, [d(atleast=True), color.rgb.red])
468 c.stroke(p, [d(lcurl=None), color.rgb.green])
469 c.stroke(p, [d(rcurl=None), color.rgb.blue])
471 p.append(path.lineto(3, 3))
472 p.append(path.closepath())
474 c.stroke(p, [d, color.cmyk.Orange])
476 c=canvas.canvas()
477 dotest(c, 0, -12, "testparallel_1")
478 dotest(c, 6, 13, "testparallel_2")
479 dotest(c, 16, 12, "testlinesmoothed")
480 dotest(c, 16, 4, "testcycloid")
481 dotest(c, 20, -10, "testcornersmoothed")
482 c.writeEPSfile("test_deformer", page_paperformat=document.paperformat.A4, page_rotated=0, page_fittosize=1)
483 c.writePDFfile("test_deformer")
484 c.writeSVGfile("test_deformer")
486 # vim:foldmethod=marker:foldmarker=<<<,>>>