```
newPage(500, 500)
fill(1)
rect(0, 0, 500, 500)
translate(250, 250)
path = BezierPath()
path.moveTo((50, -50))
path.lineTo((50, 50))
path.lineTo((-50, 50))
stroke(0)
strokeWidth(50)
lineJoin('bevel')
lineCap('square')
drawPath(path)
saveImage('~/Desktop/crouwel_test.jpg')
```

gives me:

which is not as deep a bevel as Crouwel used—it essentially makes it look as if Crouwel folded ribbons at 90deg to make his letterforms:

I've tried setting the bevel at a negative number, but no luck. Any ideas?

]]>```
newPage(500, 500)
fill(1)
rect(0, 0, 500, 500)
translate(250, 250)
path = BezierPath()
path.moveTo((50, -50))
path.lineTo((50, 50))
path.lineTo((-50, 50))
stroke(0)
strokeWidth(50)
lineJoin('bevel')
lineCap('square')
drawPath(path)
saveImage('~/Desktop/crouwel_test.jpg')
```

gives me:

which is not as deep a bevel as Crouwel used—it essentially makes it look as if Crouwel folded ribbons at 90deg to make his letterforms:

I've tried setting the bevel at a negative number, but no luck. Any ideas?

]]>```
canvas = 720
cellX = canvas/6
cellY = canvas/6
width = cellX/6 * 2
nodes = [
(-cellX, cellY * 2),
(cellX, cellY * 2),
(-cellX, cellY),
(0, cellY),
(cellX, cellY),
(-cellX, 0),
(cellX, 0),
(-cellX, -cellY),
(0, -cellY),
(cellX, -cellY),
(-cellX, -cellY * 2),
(cellX, -cellY * 2)]
segs = [
[0, 0],
[0, 1],
[0, 2],
[1, 1],
[1, 4],
[2, 3],
[2, 4],
[2, 5],
[3, 4],
[3, 8],
[4, 6],
[5, 6],
[5, 7],
[6, 9],
[7, 8],
[7, 9],
[7, 10],
[8, 9],
[9, 11],
[10, 10],
[10, 11],
[11, 11]
]
for r in range(0, 512):
newPage(canvas, canvas)
fill(1)
rect(0, 0, canvas, canvas)
translate(canvas/2, canvas/2)
count = bin(r)[2:]
count = count.zfill(22)
count = count[::-1]
for n in range(len(nodes)):
fill(1, 0, 0)
oval(nodes[n][0] - 5, nodes[n][1] - 5, 10, 10)
path = BezierPath()
fill(None)
strokeWidth(width)
stroke(0)
lineJoin('bevel')
lineCap('square')
glyph = []
for d in range(len(count)):
if count[d] == '1':
path.moveTo(nodes[segs[d][0]])
path.lineTo(nodes[segs[d][1]])
path.closePath()
drawPath(path)
```

and here's an example of what it produces that I'm trying to avoid (the red circles show node locations):

I would encourage you to have a look at the outline pen from the outliner extension

To combine several lines its best to draw them together in a `BezierPath`

so the new alphabet could be rendered with different stroke weights

scaling in the x

or y direction

and there could be multi-liners

seems like i did not compensate for the stroke weight at the end of a stroke but the system could be used for any collection of xy-points

it is all a bit messy but let me know if you need some bits.

]]>I had a look at my code and tried to tidy the worst bits. some of the angle calculations seem very inefficient but ¯\*(ツ)*/¯ here it is:

**EDIT 2018-05-28** changed the code to simplify some of the horrible trigonometry and there now is the `sq_cap`

bool to have squared linecaps.

```
# Draw a 'folded outline' between a set of points.
# TO DO: There should be an error message when two dots are closer to each other and the weight.
# There should be a warning if the folding is further than the next points.
# There should be a warning for collinear points.
import math
# Just a bunch of points
p01 = (894, 334)
p02 = (808, 86)
p03 = (274, 792)
p04 = (481, 920)
p05 = (583, 730)
p06 = (85, 430)
p07 = (318, 100)
p08 = (870, 600)
p09 = (720, 690)
points = [p01, p02, p03, p04, p05, p06, p07, p08, p09]
def get_dist(p1, p2): return sqrt( (p2[0] - p1[0] )**2 + (p2[1] - p1[1])**2 )
def calc_angle(p1, p2): return atan2((p2[1] - p1[1]), (p2[0] - p1[0]))
def calc_delta(p1, p2, p3):
'''
Returns the angle between three points.
'''
return calc_angle(p2, p3) - calc_angle(p2, p1)
def calc_offset(weight, p1, p2, p3):
'''
Returns the x and y "offset" to be added to the points of the polygon.
'''
halfWeight = weight/2
if p1 == p2:
alpha = calc_angle(p1, p3)
b = -sin(alpha) * halfWeight
a = cos(alpha) * halfWeight
elif p2 == p3:
alpha = calc_angle(p1, p3)
b = sin(alpha) * halfWeight
a = -cos(alpha) * halfWeight
else:
alpha = calc_angle(p2, p3)
delta = calc_delta(p1, p2, p3)
xx = halfWeight / sin((delta - pi) / 2)
delta_f = (2 * alpha - pi - delta ) / 2
a, b = xx * sin(delta_f), xx * cos(delta_f)
return a, b
def wrap_line(p1, p2, p3, p4, weight):
'''
This draws a polygon around a line. Four points (x,y) and a weight parameter are required.
The polygon will be drawn around the two middle points.
The first and last points define the angles.
'''
a, b = calc_offset(weight, p1, p2, p3)
# extend first point
x1b, y1b = p2[0] - b, p2[1] - a
x1c, y1c = p2[0] + b, p2[1] + a
# extend second point
c, d = calc_offset(weight, p2, p3, p4)
x2b, y2b = p3[0] - d, p3[1] - c
x2c, y2c = p3[0] + d, p3[1] + c
polygon((x1b, y1b), (x1c, y1c), (x2b, y2b), (x2c, y2c))
# --------------------------------------------------------------------
# The actual drawing
fill(0, .4)
weight = 180
sq_cap = True
if len(points) == 1:
rect(points[0][0] - weight/2, points[0][1] - weight/2, weight, weight)
for i, point in enumerate(points[:-1]):
# print (get_dist(point, points[i+1]))
if len(points) == 2:
wrap_line(points[i], points[i], points[i+1], points[i+1], weight)
else:
if i == 0:
aaa = calc_angle(points[i], points[i+1])
if sq_cap:
point = point[0] - weight/2 * cos(aaa), point[1] - weight/2 * sin(aaa)
wrap_line(point, point, points[i+1], points[i+2], weight)
elif i == len(points)-2:
next_p = points[i+1]
aaa = calc_angle(points[i], next_p)
if sq_cap:
next_p = next_p[0] + weight/2 * cos(aaa), next_p[1] + weight/2 * sin(aaa)
wrap_line(points[i-1], points[i], next_p, next_p, weight)
else:
# print ( calc_delta(points[i-1], points[i], points[i+1]) )
wrap_line(points[i-1], points[i], points[i+1], points[i+2], weight)
```

]]>`len(points) == 2`

option. but great you figured it out anyway,good luck! ]]>