3d function plots
[PyX/mjg.git] / test / functional / test_deformer.py
blob5443f4a93397426a66f87df0f4d7f74f32889812
1 #!/usr/bin/env python
2 import sys; sys.path[:0] = ["../.."]
3 import warnings
4 from pyx import *
5 from pyx.deformer import *
7 ##### helpers ##############################################################
9 def bboxrect(cmd):
10 return cmd.bbox().enlarged(5*unit.t_mm).rect()
12 def dotest(c, x, y, test):
13 c2 = c.insert(canvas.canvas([trafo.translate(x, y)]))
14 eval("%s(c2)" % test)
15 c.stroke(bboxrect(c2))
17 def drawpathwbbox(c, p):
18 c.stroke(p, [color.rgb.red])
19 np = p.normpath()
20 c.stroke(np, [color.rgb.green, style.linestyle.dashed])
21 c.stroke(bboxrect(p))
23 ##### tests ################################################################
25 def testcycloid(c):
27 # dependence on turnangle
28 p = path.line(0, 0, 3, 0)
29 c.stroke(p, [style.linewidth.THIN])
30 cyc = cycloid(halfloops=3, skipfirst=0.5, skiplast=0.5, curvesperhloop=2)
31 c.stroke(p, [cyc(turnangle=00)])
32 c.stroke(p, [cyc(turnangle=22), color.rgb.red])
33 c.stroke(p, [cyc(turnangle=45), color.rgb.green])
34 c.stroke(p, [cyc(turnangle=67), color.rgb.blue])
35 c.stroke(p, [cyc(turnangle=90), color.cmyk.Cyan])
37 # dependence on curvesperloop
38 p = path.curve(5, 0, 8, 0, 6, 4, 9, 4)
39 c.stroke(p)
40 cyc = cycloid(halfloops=16, skipfirst=0, skiplast=0, curvesperhloop=1)
41 c.stroke(p, [cyc(curvesperhloop=2)])
42 c.stroke(p, [cyc(curvesperhloop=3), color.rgb.red])
43 c.stroke(p, [cyc(curvesperhloop=4), color.rgb.green])
44 c.stroke(p, [cyc(curvesperhloop=10), color.rgb.blue])
46 # extremely curved path
47 p = path.curve(0,2, 0.5,5, 1,6, 2,2)
48 c.stroke(p)
49 cyc = cycloid(radius=0.7, halfloops=7, skipfirst=0, skiplast=0, curvesperhloop=1)
50 c.stroke(p, [cyc(curvesperhloop=2)])
51 c.stroke(p, [cyc(curvesperhloop=3), color.rgb.red])
52 c.stroke(p, [cyc(curvesperhloop=4), color.rgb.green])
53 c.stroke(p, [cyc(curvesperhloop=50), color.rgb.blue])
56 def testsmoothed(c):
57 p = path.path(
58 path.moveto(0,0),
59 path.lineto(3,0),
60 path.lineto(5,7),
61 path.curveto(0,10, -2,8, 0,6),
62 path.lineto(0,4),
63 # horrible overshooting with obeycurv=1
64 #path.lineto(-4,4), path.curveto(-7,5, -4,2, -5,2),
65 path.lineto(-4,3), path.curveto(-7,5, -4,2, -5,2),
66 #path.arct(-6,4, -5,1, 1.5),
67 #path.arc(-5, 3, 0.5, 0, 180),
68 path.lineto(-5,1),
69 path.lineto(-0.2,0.2),
70 path.closepath()
71 ) + path.circle(0,1,2)
73 c.stroke(p, [color.gray(0.8), style.linewidth.THICk])
74 c.stroke(p.normpath(), [color.gray(0.8), style.linewidth.THICk])
75 c.stroke(p, [smoothed(radius=0.85, softness=1, obeycurv=1), style.linewidth.Thin])
76 c.stroke(p, [smoothed(radius=0.85, softness=1, obeycurv=0), color.rgb.red])
77 c.stroke(p, [smoothed(radius=0.20, softness=1, obeycurv=0), color.rgb.green])
78 c.stroke(p, [smoothed(radius=1.20, softness=1, obeycurv=0), color.rgb.blue])
80 p = path.path(
81 path.moveto(0,10),
82 path.curveto(1,10, 4,12, 2,11),
83 path.curveto(4,8, 4,12, 0,11)
85 c.stroke(p, [color.gray(0.8), style.linewidth.THICk])
86 c.stroke(p.normpath(), [color.gray(0.8), style.linewidth.THICk])
87 c.stroke(p, [smoothed(radius=0.85, softness=1, obeycurv=1), style.linewidth.Thick])
88 c.stroke(p, [smoothed(radius=0.85, softness=1, obeycurv=0), color.rgb.red])
89 c.stroke(p, [smoothed(radius=0.20, softness=1, obeycurv=0), color.rgb.green])
90 c.stroke(p, [smoothed(radius=1.20, softness=1, obeycurv=0), color.rgb.blue])
93 def hard_test(c, p, dist, pardef, move=(0, 0), label=""):
94 print "hard test of parallel: ", label
95 p = p.transformed(trafo.translate(*move))
96 c.text(move[0], move[1], label)
97 c.stroke(p)
98 pps = []
99 if 1:
100 p1 = pardef(distance=+dist).deform(p)
101 c.stroke(p1, [color.rgb.red])
102 pps.append(p1)
103 if 1:
104 p2 = pardef(distance=-dist).deform(p)
105 c.stroke(p2, [color.rgb.blue])
106 pps.append(p2)
107 return
108 for pp in pps:
109 for nsp in pp.normsubpaths:
110 beg, end = nsp.at_pt([0, len(nsp)])
111 begn, endn = nsp.rotation([0, len(nsp)])
112 if begn is normpath.invalid:
113 begn = (1, 0)
114 else:
115 begn = begn.apply_pt(0, 1)
116 if endn is normpath.invalid:
117 endn = (1, 0)
118 else:
119 endn = endn.apply_pt(0, 1)
120 l = 0.1
121 c.stroke(path.line_pt(beg[0]-l*begn[0], beg[1]-l*begn[1], beg[0]+l*begn[0], beg[1]+l*begn[1]), [color.rgb.green])
122 c.stroke(path.line_pt(end[0]-l*endn[0], end[1]-l*endn[1], end[0]+l*endn[0], end[1]+l*endn[1]), [color.rgb.green])
123 for nspitem in nsp.normsubpathitems:
124 if isinstance(nspitem, normpath.normcurve_pt):
125 c.fill(path.circle(nspitem.x1_pt*unit.u_pt, nspitem.y1_pt*unit.u_pt, 0.025), [color.rgb.green])
126 c.fill(path.circle(nspitem.x2_pt*unit.u_pt, nspitem.y2_pt*unit.u_pt, 0.025), [color.rgb.green])
127 c.fill(path.circle(nspitem.atbegin_pt()[0]*unit.u_pt, nspitem.atbegin_pt()[1]*unit.u_pt, 0.02))
128 c.fill(path.circle(nspitem.atend_pt()[0]*unit.u_pt, nspitem.atend_pt()[1]*unit.u_pt, 0.02))
130 for nsp in p.normpath().normsubpaths:
131 for nspitem in nsp.normsubpathitems:
132 c.fill(path.circle(nspitem.atbegin_pt()[0]*unit.u_pt, nspitem.atbegin_pt()[1]*unit.u_pt, 0.02), [color.rgb.red])
133 c.fill(path.circle(nspitem.atend_pt()[0]*unit.u_pt, nspitem.atend_pt()[1]*unit.u_pt, 0.02), [color.rgb.red])
136 def testparallel_1(c):
138 d = c
140 # HARD TESTS of elementary geometry:
142 # test for correct skipping of short ugly pieces:
143 move = (-2, 0)
144 p = path.path(path.moveto(0, 1), path.lineto(10, 0.3), path.lineto(12, 0), path.lineto(0, 0))
145 p.append(path.closepath())
146 hard_test(c, p, -0.2, parallel(0.0), move, "A")
147 hard_test(c, p, -0.25, parallel(0.0, sharpoutercorners=1), move, "A")
149 # test non-intersecting/too short neighbouring pathels
150 move = (0, 4)
151 p = path.curve(0,0, 0,1, 1,2, 2,0)
152 p.append(path.lineto(2.1, 0.1))
153 p.append(path.lineto(1.6, -2))
154 p.append(path.lineto(2.1, -2))
155 p.append(path.lineto(-0.15, 0))
156 p.append(path.closepath())
157 hard_test(c, p, 0.3, parallel(0.0), move, "B")
158 hard_test(c, p, 0.05, parallel(0.0), move, "B")
159 hard_test(c, p, 0.3, parallel(0.0, sharpoutercorners=1), move, "B")
160 hard_test(c, p, 0.02, parallel(0.0, sharpoutercorners=1), move, "B")
162 # test extremely sensitively:
163 move = (3.5, 2)
164 p = path.curve(0,0, 0,1, 1,1, 1,0)
165 p.append(path.closepath())
166 hard_test(c, p, -0.1, parallel(0.0), move, "C")
167 # takes quite long:
168 hard_test(c, p, -0.1, parallel(0.0, relerr=1e-15, checkdistanceparams=[0.5]), move, "C")
170 # test for numeric instabilities:
171 move = (6, 2)
172 p = path.curve(0,0, 1,1, 1,1, 2,0)
173 p.append(path.closepath())
174 hard_test(c, p, -0.1, parallel(0.0, relerr=0.15, checkdistanceparams=[0.5]), move, "D")
175 hard_test(c, p, -0.3, parallel(0.0), move, "D")
177 # test for an empty parallel path:
178 move = (5, 5)
179 p = path.circle(0, 0, 0.5)
180 hard_test(c, p, 0.55, parallel(0.0), move, "E")
181 hard_test(c, p, 0.499999, parallel(0.0), move, "E")
183 # a degenerate path:
184 move = (12, 3)
185 p = path.curve(0,0, 0,-5, 0,1, 0,0.5)
186 # hard_test(c, p, 0.1, parallel(0.0), move, "F")
188 # test for too big curvatures in the middle:
189 move = (9, 2.5)
190 p = path.curve(0,0, 1,1, 1,1, 2,0)
191 hard_test(c, p, -0.4, parallel(0.0, relerr=1.0e-2), move, "G")
192 hard_test(c, p, -0.6, parallel(0.0, relerr=1.0e-2), move, "G")
193 hard_test(c, p, -0.8, parallel(0.0, relerr=1.0e-2), move, "G")
194 hard_test(c, p, -1.2, parallel(0.0), move, "G")
196 # deformation of the deformation:
197 move = (9, 6)
198 p = path.curve(0,0, 1,1, 1,1, 2,0)
199 c.stroke(p, [trafo.translate(*move)])
200 p = parallel(-0.4, relerr=1.0e-2).deform(p)
201 hard_test(c, p, -0.39, parallel(0.0), move, "H")
203 # test for infinite curvature in the middle:
204 move = (9, 8)
205 p = path.curve(0,0, 1,1, 0,1, 1,0)
206 hard_test(c, p, -0.2, parallel(0.0), move, "I")
208 # test for infinite curvature at the end:
209 move = (5, 8)
210 p = path.curve(0,0, 1,1, 1,0, 1,0)
211 hard_test(c, p, -0.1, parallel(0.0), move, "J")
212 # test for infinite curvature when the path goes on
213 p.append(path.rlineto(1, 0))
214 hard_test(c, p, -0.22, parallel(0.0), move, "J")
216 # test for too big curvature in the middle, the non-intersecting case
217 move = (2, 6)
218 p = path.path(path.moveto(0,0), path.curveto(0,5, -4,1, 1,1))
219 hard_test(c, p, 0.7, parallel(0.0, dointersection=0), move, "K")
221 def testparallel_2(c):
223 d = c
225 # a path of two subpaths:
226 move = (0, 0)
227 p = path.circle(-6, 0, 2)
228 p += path.path(path.moveto(0,0), path.curveto(0,16, -11,5, 5,5))
229 p += path.path(path.lineto(5,4), path.lineto(7,4), path.lineto(7,6), path.lineto(4,6),
230 path.lineto(4,7), path.lineto(5,7), path.lineto(3,1), path.closepath())
231 p = p.transformed(trafo.scale(0.5))
232 hard_test(c, p, 0.05, parallel(0.0), move, "Z")
233 hard_test(c, p, 0.3, parallel(0.0), move, "Z")
234 hard_test(c, p, 0.6, parallel(0.0), move, "Z")
237 c=canvas.canvas()
238 dotest(c, 13, 15, "testcycloid")
239 dotest(c, 20, 0, "testsmoothed")
240 dotest(c, 0, 0, "testparallel_1")
241 dotest(c, 6, 13, "testparallel_2")
242 c.writeEPSfile("test_deformer", paperformat=document.paperformat.A4, rotated=1, fittosize=1)
243 c.writePDFfile("test_deformer")