Line Join Studies
This page presents some studies of line joins. The studies were prompted by the question: What is the best fallback for the 'arcs' 'line-join' value when the two arcs don't meet? The studies are intertwined and thus presented on one page.
- Large stroke widths.
- Fallback for 'miter-clip' line join.
- Fallback for 'arcs' line join.
Before we head to the studies, there are two principles to guide us:
- Small changes in the should not result in large visible changes in line joins.
- The shapes of the line joins should be easy to calculate.
Large stroke widths
Joining lines when the curvature of radius is less than half the stroke width
SVG 1.1 'line-join' values have one important problem. When the radius of curvature of a path segment at a line join is less that half the stroke width, one of the off-set paths at the stroke edge is moving backwards. If this edge is on the outer side of the line join it creates a problem as can be in the following figure:
The algorithm for constructing line joins starts with the two points at the ends of the outer offset paths, shown by black dots in the above figure. A 'bevel' line join is constructed by drawing a straight line between the two end points which, in the above example, leads to a strange projection on the bottom right side.
A 'round' line join is constructed by drawing an arc with a radius of half the stroke-width between the two end points. Note, that this will always "fill in" the region created by the backwards motion of the offset path, although, as can be seen below (second row), there can be abrupt changes in the outer stroke edge at the start and end of the line join.
A 'miter' line join is constructed by taking the tangents of the offset path segments at their ends and extending them until they intersect. If they don't intersect (since they are parallel) or if the intersection is too far away (exceeding the value of the 'miter-limit' property), a 'bevel' line join is constructed instead.
In the following diagram, each type of line join is drawn both where the radius of curvature at the end of the path segments at the line join is greater than half the stroke width and where one or both curvatures is less than half the stroke width.
One idea to improve the look of line joins when the offset path moves backwards is to use the point when the tangent flips as the end-point. (This is represented by green lines in the figure above and the light-green area in the figure below.)
Using the point where the tangent flips sign does yield better looking line joins in almost all cases but it also adds the requirement of locating the point at which the tangent flips (the point where the curvature exactly equals the stroke width). This contradicts our second goal. There doesn't seem to be a good solution to this problem.
Fallback for 'miter-clip' line join.
The new (in SVG 2) 'miter-clip' value for line joins has a much more sensible behavior than the old 'miter' value for when the miter length exceeds the miter limit value. There is still one potential problem. In animating a path where the angle between the incoming and outgoing segments changes sign, there is an instance where the incoming and outgoing paths segments are parallel at the line join. The SVG 2 spec at the moment is not clear what one does in this case. It can be assumed for the 'miter' line join that one falls back to a 'bevel' line join. For the 'miter-limit' case it would be more desirable to simply continue to clip to the 'miter-limit'. In any case it needs to be made more clear that step (4.) in the section that describes how to construct the line join shape applies only to path segments with the same direction.
Fallback for 'arcs' line join.
What is the best fall-back solution for the 'arcs' line join when the arcs don't intersect? The currently specified fallback to a 'miter' line join is not ideal. Can we do better? There are several possibilities:
- Replace the smaller arc by a straight line.
- Decrease the curvature (i.e. increase the radius) of the inner arc until the two arcs intersect.
- Decrease the curvature (i.e. increase the radius) of the inner arc and increase the curvature of the outer arc until the two arcs intersect.
Here are some animations of the various fallback possibilities. Note: the animations are quite crude and a SMIL enabled browser is required. Also, the choice of using a thick stroke-width magnifies the problem.
Options 2 and 3 produce the nicest fallbacks. The line join does become quite long when the incoming and outgoing path segments are parallel. These fallbacks do require a bit more math but nothing outrageous. Option 2 is a special case of Apollonius' problem for a point, line, and curve where the point is on the line. Option 3 requires solving a quadratic.
Here is a direct comparison of options 2 and 3:
Option 1 is simple to calculate. It does produce a nicer fallback than the 'miter' fallback. It works well when the curvatures of the incoming and outgoing path segments have opposite sign. When they have the same sign it is probably best to still fallback to a 'miter' line join (see next figure).
A comprehensive study of the 'arcs' line join follows showing the effects of various curvatures and angles of the path segments at the joins. The light gray areas show the currently specified behavior of the 'arcs' line join (as implemented in Inskcape using a Live Path Effect. In some cases alternative fallbacks are shown (pink, dark gray).
Here is an example where using a different fallback than 'miter' improves the look of the drawing.