Re: SVG2 - suggestion for a new path command to close a subpath smoothly

From: Dr. Olaf Hoffmann <Dr.O.Hoffmann@gmx.de>
Date: Sat, 8 Dec 2012 17:49:58 +0100

Message-Id: <201212081749.58542.Dr.O.Hoffmann@gmx.de>
Rik Cabanier:
> Hi,
>
> It would be good to see the formula's that derive the strength of the
> control points.

Note, that my suggestion provides only a smooth close of a path,
if at least the first and last segments of such a subpath are cubic
segments. This is the point, where this new command aligns
with the S command - as defined currently, you will typically
get no smooth continuation with S, if the previous segment
is no cubic segment.

Construction instructions are added below including an idea, how
to extent it to quadratic and affine segments.

> Even better would be a small library that implements them
> so  people can experiment with the results.

I used a PHP-script with random path data.
If I find it, I can put it from my test server to a public server,
maybe with some modifications.

> Thinking about it some more, I'm less concerned with arc since the
> 'direction' of the last control point is probably constant with respect to
> precision.
> We'd still need to specify what would happen to Catmull-Rom.
>

There are no formulas mentioned for this new method at all
in the current draft - needs to be done.
However, if my understanding is correct, it is some kind of
cubic interpolation/spline for a given set of points.
For the methods I know to do this, there are always
formulas for closed (periodic conditions) and for open paths -
different boundary conditions only.
The open path conditions are slightly more complex and problematic
than those for the closed path.
Therefore one only needs a flag to indicate, which rules have
to be used.

_____________________________________________________________
Formulas for cubic path extensions and how to use them to close a cubic path
smoothly

A cubic path segment can be described with the parametrisation
(s from 0 to 1; P(0) initial point, P(1) first control point, P(2) second
control point,  P(3) final point)

k(s) = (1 - s)³P(0) + 3s(1-s)²P(1) + 3s²(1-s)P(2) + s³P(3)

derivations:
dk(s)/ds = (1 - s)² (3P(1) - 3P(0)) + 2s(1-s) (3P(2) - 3P(1)) + s²(3P(3) -
3P(2))

d²k(s)/ds² = (1-s) (6P(0) - 12P(1) + 6P(2)) + s (6P(3) -12P(2)) + 6P(1))
(not used in the following, but another option to get 'even more smooth
paths'.)

Especially at the beginning and the end:
dk(0)/ds = -3P(0) + 3P(1)
dk(1)/ds = -3P(2) + 3P(3)

or

P(1) = P(0) + dk(0)/ds/3
P(2) = P(3) - dk(1)/ds/3

Note, that if you want to get the current direction of the path,
for example to align markers correctly, you get in trouble with
these formulas, if P(0) = P(1) or P(2) = P(3).
You need L'Hôpital's rule to analyse these specific cases.
It turns out, that if not both control points are coincident with the point,
you need to get the direction for, you can simply use the other control point,
else you can use the other point, if not all four points are the same,
only then there is no direction for the segment.

To continue with another segment behind this segment,
one has to continue with the same direction.

A = dk(1)/ds = -3P(2) + 3P(3) (old segment)

To get the new points, one can use a positive number a:

P(0, new) = P(3, old)
P(1, new) = P(3, old) + a A/3

The S command uses a = 1.

To add a new segment before the old segment, one has
to use the formular correspondingly:

A = dk(0)/ds = -3P(0) + 3P(1) (old segment)

To get the new points, one can use a positive number b:

P(3, new) = P(0, old)
P(2, new) = P(0, old) -b A/3

To close a subpath, one can obviously write with P(i,0)
points of the first segment and P(i,n) points of the
last segment:

P(3, n) = P(0, 0)
P(2, n) = P(0, 0) -b A/3
following the strategy of the S command we use b = 1,
therefore we get:

P(2, n) = 2 P(0, 0) - P(1,0)

Simple fallback rule for unsuitable path data:
For the S,s commands we have already a rule,
if the previous segment is no cubic segment:
P(1)=P(0)

We use the corresponding rule for the new
curved close path command, if the initial
subpath segment is no cubic segment:
P(2,n) = P(3,n) = P(0,0).

If we want better rules, first we have to define
parametrisations of cubic, quadratic and affine
segments used to transform a quadratic or affine
curve into a cubic - there are canonical parametrisations
as that above for the cubic path, therefore no problem
to do this (it is an arbitrary choice, as usual).
Having this, one can apply the above formulas to
close other path data as well in most cases smoothly.
An advanced method would be to allow authors to
provide the numbers a, respectively b, but we
do not have this currently for S,s.
Therefore I think, the simple rule should be
sufficient for most practical use cases - typically
if one works with paths without corners, one will
use cubic paths anyway.
Received on Saturday, 8 December 2012 16:50:28 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 8 March 2017 09:47:30 UTC