properly apply skippedline by the new flushskippedline method
[PyX/mjg.git] / examples / path / knot.py
blob36d6db25f5276f4dab625ecb13afaf28960f1003
1 from pyx import *
2 unit.set(uscale=3, wscale=3)
4 dist = 0.15 # distance between the ropes
5 thick = 0.08 # thickness of the ropes
7 # build the basepath of the knot. This is the curve that lies
8 # between both ropes.
9 A = 1.0, 0.1 # point where the knot starts after the straight line
10 B = 1.3, 0 # point where the knot is curved, overlying the straight line
11 t = -0.8, -0.1 # direction at A
12 s = 0.3, 1.2 # direction at B
13 pts = [
14 ( A[0]-t[0], A[1]-t[1]), ( A[0] , A[1] ),
15 ( A[0]+t[0], A[1]+t[1]), (-B[0]-s[0],-B[1]-s[1]),
16 (-B[0] ,-B[1] ), (-B[0]+s[0],-B[1]+s[1]),
17 ( B[0]-s[0], B[1]-s[1]), ( B[0] , B[1] ),
18 ( B[0]+s[0], B[1]+s[1]), (-A[0]-t[0],-A[1]-t[1]),
19 (-A[0] ,-A[1] ), (-A[0]+t[0],-A[1]+t[1]) ]
20 seam = path.path(
21 path.moveto(*(pts[0])),
22 path.lineto(*(pts[1])),
23 path.curveto(pts[2][0],pts[2][1],pts[3][0],pts[3][1],pts[4][0],pts[4][1]),
24 path.curveto(pts[5][0],pts[5][1],pts[6][0],pts[6][1],pts[7][0],pts[7][1]),
25 path.curveto(pts[8][0],pts[8][1],pts[9][0],pts[9][1],pts[10][0],pts[10][1]),
26 path.lineto(*(pts[11])) )
27 # We smooth this curve a little because we used curveto together with lineto
28 seam = deformer.smoothed(0.4).deform(seam)
31 # The ropes, when drawn later, will have to overlap in a very specific way.
32 # We need to split them at appropriate points.
33 # This gives a list of segments for the middle curve
34 l = seam.arclen()
35 seam_segs = seam.split([0.28*l, 0.42*l, 0.58*l, 0.72*l])
38 # For each segment two shifted paths build the boundaries of each rope
39 ropes_segs = []
40 for seam_seg in seam_segs:
41 ropes_segs.append([])
42 for ropeshift in [-0.5*dist, 0.5*dist]:
43 ropes_segs[-1].append([])
44 for edgeshift in [-0.5*thick, 0.5*thick]:
45 # We use the parallel deformer to create the parallel segments
46 # for each rope from the base curve:
47 ropes_segs[-1][-1].append(
48 deformer.parallel(ropeshift + edgeshift).deform(seam_seg))
49 # Now, ropes_segs is a list of segments, containing a list of ropes,
50 # each containing the two bounding paths of the rope segment
53 rope_colors = [color.rgb.blue, color.rgb.red]
55 c = canvas.canvas()
56 # Because the segments should overlap in a very specific manner
57 # we have to draw them in the correct order
58 for index in [1, 4, 2, 0, 3]:
59 for rope_seg, col in zip(ropes_segs[index], rope_colors):
60 seg = rope_seg[0].joined(rope_seg[1].reversed())
61 seg.append(path.closepath())
62 c.fill(seg, [col])
63 c.stroke(rope_seg[0], [style.linecap.round, style.linejoin.round])
64 c.stroke(rope_seg[1], [style.linecap.round, style.linejoin.round])
66 c.writeEPSfile("knot")
67 c.writePDFfile("knot")