Offset Bezier curves

We have spent some time here to convert a stroke path to a fill path. We made a first version of 1 pixel width strokes in 100 100 moveto 200 300 lineto stroke and improved it in Rethinking stroke to discover later A bug in the stroke algorithm and to fix it. We had to review the code when we added transparency Transparency does not work with Stroke and had to check again when we were Implementing zero winding.

In any of these algorithms, the stroke algorithm is implemented very late on chain because it works only on straight lines. So you have to convert Bezier curves to straight lines first before applying ist. It would be more elegant if we could do this directly with the Bezier curves.

This problem is called offsetting Bezier curves. It is considered as a hard problem.

We consider a parallel curve a second curve at a constant normal distance. There is not always a solution to this as shown in the Wikipedia article on parallel curves. It has been proven by Tiller and Hanson in 1984 that in general, the parallel curve of a Bézier curve is not another Bézier curve. As an approximation, they propose to offset the legs of the control polygon in perpendicular directions.

For practical applications, there are to points to consider: First, Bezier curves are only approximations of real curves in graphic design. For example, there is no combination of Bezier curves that exactly matches a circle. However, we see circles drawn with Bezier curves every day because the approximation is good enough. Second, the general case of Bezier curves deals with control points in extreme directions which are rarely used. The control points used in fonts and by professional artists in Illustrator follow some recommandations which can be handled by an approximation.

We try the following approximation: The endpoint are offset a 90 degrees from the line to the control point. A cubic interpolation point is calculated. This point is offset at 90 degrees to the line between the control points. Then the control point vectors are scaled by the relative distances between the midpoints and the endpoints. This works better for angles less than 180 degrees but less if both control points are on the opposite side.

Javascript Editor

Let's try Tiller and Hanson, if the offsetting legs is getting better results. Lines are not really better and there is an ugly edge case if the leg line is parallel to the angle of the two control points.

Javascript Editor

So we stay with our first method and define a rounded pen, that is a stroke with rounded ends and even straight lines.

Javascript Editor

Having this, we can define glyphs of a simple rounded font

Javascript Editor

My Journey to PostScript