Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Path.simplify() sometimes results in control points that are nowhere near the line #414

calamitas opened this Issue Mar 3, 2014 · 9 comments


None yet
2 participants

calamitas commented Mar 3, 2014

The sketch below shows this behavior. The lower line shows the simplified path where one control points sticks out below. Increasing the tolerance to 10 seems to fix the problem.

We see this issue a lot in our application, especially when we use Path.simplify while drawing live; sometimes the line jumps to the edge of the screen and then goes back.

Simply changing the tolerance doesn't fix it completely as things can still go wrong (see second sketch below).

Any ideas on how to fix this? The path simplifying in paper.js is great except that it sometimes gives these weird artefacts.



@calamitas calamitas closed this Mar 5, 2014

@calamitas calamitas reopened this Mar 5, 2014


calamitas commented Mar 5, 2014

After looking at the PathFitter code, it's obvious that the least squares method doesn't care whether or not the curve contains any of these big jumps as long as the total error is minimal. I fixed it in our code for now by checking if either of the alphas is too large and reverting to the 1/3 rule in that case (same as for alphas that are too small). At the moment, I check if either alpha is larger than segLength, but this can be refined to check for control points that are 'out of order'.

A second possible issue from an inspection of the code is that reparameterize can generate values for u that are out of order. As you know, Newton-Raphson can overshoot the root, sometimes by a lot, and this causes a later u value to become smaller than an earlier one. I checked and this actually happens for almost any line I draw as long as it is not too straight. Although I haven't found a case where it happens, it is at least theoretically possible that a Bezier can be fitted for this new parameterization. The resulting curve would then hit (or nearly hit) the points in the wrong order.


calamitas commented Mar 6, 2014

Note also that when reparameterize generates u values outside of the range 0 to 1 for some points, the resulting curve segment won't even hit those points.


lehni commented Mar 6, 2014

Great, thanks for looking into this! The code was ported over from Graphic Gems (http://iut-arles.univ-provence.fr/web/romain-raffin/sites/romain-raffin/IMG/pdf/PSchndeider_An_Algorithm_for_automatically_fitting_digitized_curves.pdf)

Would you like to try and fix these errors?


lehni commented Jan 15, 2015

@calamitas would you be willing to share your changes to the code? I'd be happy to accept a pull request.


calamitas commented Jan 15, 2015

Sorry, totally forgot about this.

We used this for a client and I'd have to check with said client to see if we can share the code. If not, I'll recode it in my spare time. I don't know when I'll get around to it as I have little free time for the moment due to a 4 month old baby requiring attention.


lehni commented Jan 15, 2015

Good to hear. I hope the client is happy to give something back, given the fact they're building on a lot of work that we happily contribute.

@calamitas calamitas added a commit to calamitas/paper.js that referenced this issue Feb 22, 2015

@calamitas calamitas Change PathFitter to constrain newly found control points. d5c25db

calamitas commented Feb 22, 2015

Well, we never got an answer from the client, so I suppose the answer is no.

At someone else's request, I redid the fix. You can find the commit here: calamitas/paper.js@d5c25db .

If you want a test written for the fix, I'll be glad to do so when I find the time. Then I'll send you a pull request.


lehni commented Apr 4, 2015

This is great, thanks a lot! I'll review and merge this in now. Apologies for taking so long to respond.


lehni commented Apr 4, 2015

Fixed in faecea3

@lehni lehni closed this Apr 4, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment