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.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
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
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 # 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
]
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())
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")