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.

  1. Large stroke widths.
  2. Fallback for 'miter-clip' line join.
  3. Fallback for 'arcs' line join.

Before we head to the studies, there are two principles to guide us:

  1. Small changes in the should not result in large visible changes in line joins.
  2. The shapes of the line joins should be easy to calculate.

Large stroke widths
or
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:

A path with a stroke width of 200 pixels. The radius of curvature for the left end of the right path segment is less that 100 pixels leading to the offset path at the stroke edge moving "backwards." The path data is shown in purple. The offset paths (before line joining) are shown in red with the "reversed" part overlaid with a blue dash. The black dots represent the ends of the offset paths that are used to construct the line join. For a 'bevel' line join the two ends are connected by a straight line.

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.

First and third rows: the radius of curvature is always greater than half the stroke width everywhere along the path. Second and fourth rows: the radius of curvature at the line join is smaller than half the stroke width for both paths segments (second row) or one path segment (fourth row). Purple paths: path data. Red paths: offset paths (after line joining). Green and light-blue paths: see below.

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.)

The pink area is the area filled in by a 'bevel' line join according to the algorithm of SVG 1.1. The light-green area is the area that would be filled in if the point where the tangent flips sign is used instead of the end point.

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.

One possible behavior. Note: A SMIL enabled browser is required to see the animation.

The preferred behavior. Note: A SMIL enabled browser is required to see the animation.

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:

  1. Replace the smaller arc by a straight line.
  2. Decrease the curvature (i.e. increase the radius) of the inner arc until the two arcs intersect.
  3. 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.

The currently specified fallback behavior (falling back to a 'miter' join).

Option 1: Falling back by using a straight line for the smaller arc.

Option 2: Falling back by decreasing the curvature for the smaller arc until the arcs intersect. (Note: the jerkiness of the animation is the fault of the animation method.)

Option 3: Falling back by decreasing the curvature for the smaller arc and increasing the curvature of the larger arc until the arcs intersect. (Note: the jerkiness of the animation is the fault of the animation method.)

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:

Comparison of Option 2 and Option 3 for the longest talon. Option 2 in blue; Option 3 in red.

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).

A study of the 'arcs' line join with various radii of curvature and at various angles between the incoming and outgoing path segments. k is the curvature (signed 1/radius) and w is the stroke width.

Here is an example where using a different fallback than 'miter' improves the look of the drawing.

Left: A fallback of 'miter'. Right: A fallback of keeping a curved edge on one side. (The red arrow marks the line join in question.)