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
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
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]) ]
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.6).deform(seam
)
30 # The ropes, when drawn later, will have to overlap in a very specific way.
32 epsilon
= 0.002*l
# small overlap between the segments
33 seam_segs
= seam
.split([0.28*l
+epsilon
, 0.28*l
-epsilon
,
34 0.42*l
+epsilon
, 0.42*l
-epsilon
,
35 0.58*l
+epsilon
, 0.58*l
-epsilon
,
36 0.72*l
+epsilon
, 0.72*l
-epsilon
])[::2]
38 # For each segment, two shifted paths build the boundaries of each rope
40 for seam_seg
in seam_segs
:
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 ropes_segs
[-1][-1].append(
46 deformer
.parallel(ropeshift
+ edgeshift
).deform(seam_seg
))
47 # Now, ropes_segs is a list of segments, containing a list of ropes,
48 # each containing the two bounding paths of the rope segment
50 rope_colors
= [color
.rgb
.blue
, color
.rgb
.red
]
52 # Because the segments should overlap in a very specific manner
53 # we have to draw them in the correct order
54 for index
in [1, 4, 2, 0, 3]:
55 for rope_seg
, col
in zip(ropes_segs
[index
], rope_colors
):
56 seg
= rope_seg
[0].joined(rope_seg
[1].reversed())
57 seg
.append(path
.closepath())
59 c
.stroke(rope_seg
[0], [style
.linecap
.round, style
.linejoin
.round])
60 c
.stroke(rope_seg
[1], [style
.linecap
.round, style
.linejoin
.round])
62 c
.writeEPSfile("knot")
63 c
.writePDFfile("knot")