Submitted by mark on Sun, 02/07/2016 - 21:17
Extending Philip J. Schneider's classic “An Algorithm for Automatically Fitting Digitized Curves” from two to four dimensions lets it handle pressure and rotation quite well.
Submitted by mark on Tue, 02/02/2016 - 00:38
I move an ellipse (light green) along a Bézier curve (black) and let it intersect (red) with a single normal (dark green) on that curve.
The dark blue curve represents the distance of each ellipse, the light blue curve is it's 1st derivative. Which is a polynomial of degree 18. (Thanks to the trial version of Mathematica for figuring that out.)
Which I could tackle with Newton-Horner.
And then I would have still to include rotation and pressure (scaling)...
Or I just take, say, a hundred samples, and take the maximum/minimum as start for the Newton method.
Submitted by mark on Sat, 01/09/2016 - 14:22
Inkscape uses an algorithm based on Dynadraw for it's calligraphic pencil tool. Which seems to extrude a scaled and rotated line along a path.
The algorithm others and I've been using uses an ellipse instead of a line. Which I prefer because it's closer to a real nib pen.
But my code doesn't output béziers yet, so I began playing with Tiller-Hanson's bézier offset algorithm.
But I'm not quite sure how to handle a rotated ellipse with a path offset algorithm.
Submitted by mark on Thu, 01/07/2016 - 23:16
||It's getting somewhere. Curves are now also split on vertical extrema and the sweep buffer sorting should work for curves and lines with no more than one intersection. As far as I see, getting rid of that limit plus curves intersecting with curves might be only remaining issues.
Submitted by mark on Thu, 10/22/2015 - 22:01
Got it. My mistake. I assumed that splitting curves at their horizontal extrema would be enough. But in the case below the green curve ended up above the blue curve in the sweep line buffer. That's because SweepComp is using the end points of the curve (red line) and then of course the green line ends up above the blue one.
I could solve that by also splitting curves at the vertical extremas (orange line)... or by using the left point's control point?
Submitted by mark on Sat, 10/17/2015 - 06:46
Regarding my last post I found two issues:
- The sorting order of line segments 3 and 4 in the sweep line buffer is wrong.
- Line 27 was calculated to be inside the resolution of the union operation.
Either I screwed up elsewhere, or there are still some issues in the original implementation. *sigh* And it all looked so good a few days ago.
Submitted by mark on Sun, 10/11/2015 - 14:19
Slowly getting there. paper.js's solveCubic() algorithm lacked precision so I replaced it with the one from the GNU Scientific Library whose algorithm has street cred for about 500 years. I also simplified the way curves are stored, which resolved another source of issues.
In the picture below I fail to find the intersection between the segments number 3 and 31:
Submitted by mark on Sun, 10/04/2015 - 13:50
I began extending the algorithm to handle paths containing Bézier curve segments:
This shows how far I've got. After the next step everything will drown in errors.
Submitted by mark on Wed, 09/30/2015 - 00:05
Guess what! After fixing the 3rd issue, the algorithm suddenly feels stable. And because I'm so happy about it, below is a picture of my scribbling paper used to get there. Oh the irony of it: Requiring paper to get rid of paper. :)
Submitted by mark on Sun, 09/27/2015 - 16:23
I replaced the algorithm which calculates the line intersections. The next class of errors are cases where dividing a line would place it somewhere else within the sweep line buffer. Currently the line's flags are calculated, then the line is divided and because the division might have changed the position of some lines in the sweep line buffer, the flags are recalculated for some known cases.
I found one case where this didn't happen and it seems that there are more.
A more reliable approach might be to reevaluate the order within the sweep line buffer and act accordingly. From there I could even brute force a list of all cases where the flags need to be recalculated.