On Fri, 2012-05-18 at 10:18 +0200, Jasper van de Gronde wrote:
On 18-05-12 07:30, Tavmjong Bah wrote:
...
The extrapolation does not use the curvature of the path, but the path's direction instead. The direction of the path is then rotated 90 degrees to get the normal, which is then used to simply mirror the path itself to obtain the extrapolation. The direction is easily calculated from the derivative of the path (or 2nd derivative if 1st is zero, or 3rd if...); something like that must be already used to draw the standard SVG miter.
Ah, this explains why my first attempt at creating a demo image didn't look quite right and when I used circular arcs it looked better. When there is a large change in the rate of curvature along a path I don't think mirroring give's the best looking results. I think you want to keep the curvature constant or even the first and second derivatives constant (although the latter would be tougher to implement). When I get a chance, I'll create some tests.
Keeping both the first and second derivatives constant would indeed be hard (as in, impossible in general), but keeping their magnitude constant might be doable. In fact, this is probably equivalent to keeping the curvature constant. If I am not mistaken (with at least Wikipedia to back me up), the curvature can be defined as the magnitude of the second derivative in the arc-length parametrization.
Now, if you keep the magnitude of the first derivative the same, then you're essentially using a (scaled) arc-length parametrization. So if you then also keep the magnitude of the second derivative the same, then you're keeping the curvature the same. (Similarly, if you keep the curvature the same, there should be a parametrization such that, etc., etc.)
Assuming you use the above or some other (direct) formula to find the curvature at the end, extending the curve with constant curvature is then relatively easy. It will be a circle arc with radius 1/K (with K the curvature). The center of the circle is easy to find (normal to the curve at a distance of 1/K). You then just need to find the intersection with the other side (which is just a matter of intersecting two circles and choosing between two intersection points) and figure out a way to encode the result (but you're probably doing this all with SBasis curves anyway, so that shouldn't really be a problem). If you need more details, just ask.
My brain was obviously still sleeping when I replied... substitute second derivative for first derivative and third derivative for second in my last email. And I meant an 'or' instead of an 'and'. In other words, the simplest thing to do is to use the curvature at the end of the line to extend the curve; a perhaps better, but more difficult option, is to instead use the derivative of the curvature.