Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduce (or extrema or split?) breaks as soon as control point and start are the same #37

Open
Zylindermann opened this issue May 26, 2016 · 5 comments

Comments

@Zylindermann
Copy link

First of all thanks for that library, saved me a lot of time :-).
Apparently the reduce function fails as soon as a control point and the start/ end are the same. I did some further investigations and found out that this is connected to the extrema function yielding 0 two times and therefore "confusing" the split function (which seems to be broken for input 0,0 as well).
Minimal example below:

      var curve = new Bezier(100,25 , 100,25 , 110,100 , 150,195);
      var draw = function() {
        drawSkeleton(curve);
        drawCurve(curve);
        setColor("red");
        curve.extrema().values.forEach(function(t) {
          drawCircle(curve.get(t),3);
          console.log(t);
        });

        curve.reduce().forEach( (curve) => {
          drawCurve(curve);
        } );

      }
@Pomax
Copy link
Owner

Pomax commented May 26, 2016

Yeah there is currently no logic in place for checking curves that are obviously degenerate (exact overlapping coordinates, curves that are actually perfectly straight lines, etc)

@joostdecock
Copy link
Contributor

For those who ended up here after Googling; The same problem occurs when you try to get the .offset() of a Bezier curve that has one of it's control points identical to the start or end point.

Here's an example:

The black solid curve has it's start control point identical to its start point (the curve goes upwards). As you can see, the dotted offset stops short.

The pink curve has its control point shifted away from the start point, and as you can see, the dotted offset is correct.

If you find yourself in this situation, here is the workaround I use:

Check that start=cp1 or end=cp2. When it is, shift that control point slighty along the curve (you can use get() for that). If you shift it in some random direction, even by just a smidge, the offset will make a weird wobble at the end (not weird actually, but expected). But if you shift it along the curve, the offset will look just fine. Like this:

I'm sharing this here in the hopes it might save others some time.

@hoomanaskari
Copy link

hoomanaskari commented Feb 2, 2021

Hi, first of all, thanks for this wonderful library.

Any news on this to be fixed?

Most design apps (Sketch, Figma, Illustrator) have this feature. The solution above works only when you have 1 curve, I am building a pen tool (multiple curves and lines) with this library, everything else works like a charm, except for this 1 issue. I am trying the split the curves on a given point (mouse pointer). Works perfect when the curve is not "degenerate".

@Pomax
Copy link
Owner

Pomax commented Feb 2, 2021

I've not had any time free to work on this, unfortunately. The code solution is still "detecting degenerate curves, with special affordances for those cases", but I'm quite focussed on some license-encumbered projects atm that don't really give me much free time =(

@hfutrell
Copy link

hfutrell commented Feb 3, 2021

My code may help here. BezierKit began as a Swift port of Bezier.js. I ran into the issues with reduce() and offset() mentioned in this thread, and fixed them. They're just in Swift in stead of Javascript.

https://github.com/hfutrell/BezierKit/blob/master/BezierKit/Library/BezierCurve.swift

@joostdecock As I recall, the issue with offset() is that in the degenerate case the derivative is zero. My version gets around this by using a unit normal vector instead, where the normal is calculated carefully to work correctly in degenerate cases (so long as not all control points are equal where the normal cannot be defined).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants