-
Notifications
You must be signed in to change notification settings - Fork 747
Description
In my current font project I do extensive simplification of autotraced splines, and have generally been very pleased with the result of @linusromer's implementation of Raph Levien's curve fitting algorithm. However, it has also lead to me discovering some bugs and undesireable behaviour. Please consider the following font file, which contains a series of short curve segments, each of which demonstrates a problem: splinefit-bugs.sfd.zip
The first one simplifies to a weird, extremely compressed S-shape, which traces the original curve multiple times, by going up and down and then up again. The solution seems straightforward: when calculating the minimum quadratic distance sum, I think that the shortest distance mapping from the mid points to the approximation should be forced to be monotonic. My fix can be seen in commit 2a0b4a6 to my fork.
The second curve (in character "2") ends in a point which has a control point handle of length 0. This triggers the second bug: the tangent at the end is by mistake estimated based on the slope towards the end of the first spline, not the last. I correct this in my second commit, 15d5ca9. (I should point out though that I do not fully understand the code block at lines 751-755. Under what situation, if any, does this occur? Is the value of the temp variable correct and relevant, considering my change? Should both from->next and to->prev be set to NULL?)
That second fix also saves the third curve from becoming heavily distorted. But its simplified curve is far from ideal. Curves 4 and 5 are still distorted. However, I have found that all of these will become much improved (perfect for my needs), if I allow the handles to extend beyond the Tunni point (i.e., by not limiting aMax and bMax). (Doing so also enables the exact simplification of the constructed curve 6.) However, I acknowledge that removing this restriction generally may introduce many unwanted inflection points. I hope that it should be possible to come up with sensible criteria for when longer handles should be permissible -- perhaps it is as simple as checking if the original curve segment has an inflection point, and allow it then? But I have not thought this over in detail, and I am not sure how to implement that in the best way. What are your thoughts on this?
In any case, i.e., even if the solution isn't to twiddle with aMax and bMax, the distortion currently seen in the simplification of 4 and 5 would have to be amended somehow, of course.