Re: stroke-linejoin="arcs"

On Thu, 2015-11-26 at 18:30 -0200, Diego Nehab wrote:
> Hey guys,
> 
> I am a computer graphics researcher and have been looking into the
> new "arcs" stroke-linejoin proposal for SVG 2. Is the specification
> complete? If so, I can imagine many developers will have trouble
> sorting out the missing details. Take at look at 12.5.8 and figure 13
> at
> 
> http://www.w3.org/TR/SVG2/painting.html#CurvatureCalculation
> 
> It seems to me that easiest way to specify the center of the circle
> is relative to point P, and not relative to points P1 and P2. This is
> because we are offsetting the osculating circles to the path at P (at
> each side). The offset circle has the same center as the osculating
> circle. If the normals of the path at P are N1 and N2 and the
> curvatures are k1 and k2, the center is always at P + N1/k1 and P +
> N2/k2, regardless of the stroke-width.

It does seem to be a clearer to define the center of the circles as the
center of the osculating circle. I'll make the change. The problem with
your definition of the center is that the N1 and N2 are ambiguous in
sign.

> Once the center is fixed, we need the radius. Here, I believe the
> correct formula is abs(1/k - 0.5 stroke-width). Look at figure 13. If
> you increase the stroke width on and on, at some point P1 will cross
> the center of Aoutside. You need the abs() for this case. It is the
> sign of the curvature that tells whether we should add or subtract
> 0.5 stroke-width to the radius of curvature. The abs() allows us to
> unify everything in a single case.

This works for a path where the join is to the left of the path
(relative to the path direction) but fails if the join is to the right.
Then the radius is abs(1/k + 0.5 stroke-width). See [1]

> There also seems to be missing information on the arcs that make up
> the join:
> 
> " If the two circles (or circle and line) intersect, the line join
> region is defined by the lines that connect P with P1 and P2 and the
> arcs defined by the circles (or arc and line) between the closest
> intersection point to P, and P1 and P2. "
> 
> In the case where both curvatures are positive and both radii of
> curvature are smaller than 0.5 stroke-width, the arcs that connect P1
> to P4 and P4 to P2 are CCW (and can easily span more than 180
> degrees). In all other cases, the arcs seem to be CW.
> 
> There is an additional interesting corner case. The documentation
> mentions the cases where the points do not intersect and when both
> curvatures are zero, in which case we should fall back to miterclip.
> However, when either curvature is +/- infinite (or very large
> magnitude), it is better to revert to round instead.

Whenever the radius of curvature is less than half the stroke width the
tangent flips direction. This is not a new problem. Browsers are not
consistent in how they handle these edge cases for existing line joins
and end caps.[2][3] We should work on defining these cases better but
may be hampered by the baked in behavior of the graphics libraries that
the browsers use.

> There seems to be a a typo in "For a line: the curvature is
> infinite." I think you mean that the curvature is zero, right?

The denominator goes to zero faster than the numerator so in the limit
as P1 goes to P0, for example, the curvature goes to infinity and the
radius goes to zero. This does raise the point, that the fallback of
using a straight line should probably be changed to using a curve with
the radius of half the line width. This will take a bit of
investigation.

> At any rate, this is just a heads up and a request for
> clarifications. The more explicit the documentation is, the fewer
> confused people like me there will be.

Thanks for the feedback.

Tav
 
[1] http://tavmjong.free.fr/SVG/LINEJOIN/line_join_arcs_diagram.svg
[2] http://tavmjong.free.fr/SVG/LINEJOIN/line_join_test_all.svg
[3] http://tavmjong.free.fr/blog/?m=201504

> Kind regards,
> Diego

Received on Tuesday, 1 December 2015 14:50:39 UTC