javascriptlinebezierline-intersection

No intersection point found on line with bezier curve: (Using bezier.js by @Pomax)


Code from bezier.js works great for all other examples I've checked. Except for this one:

const controlPoints = [450,50,300,183,150,150];
const line = { p1: {x: 400, y: 0}, p2: {x: 400, y: 100} }

const intersectionPoints = [];

    
const bezierCurve = new Bezier(x1,x2,c1,c2,y1,y2);
console.log(x1,x2,c1,c2,y1,y2);
const intersections = bezierCurve.lineIntersects(line);
if (intersections.length > 0) {
   for (let e = 0; e < intersections.length; e++) {
      let n = intersections[e],
       t = bezierCurve.get(n);
       intersectionPoints.push(t);
   }
}
console.log("Intersection Points:", intersectionPoints);

return intersectionPoints;

It returns no intersection points. Although there definitely is one at around: {x: 400, y: 90/95 }

I was expecting an intersection point between the bezier curve and the specified line.


Solution

  • It seems like this is a bug in the underlying bezier.js library, it will return no intersection sometimes when intersecting with a vertical line. This can be seen in this Github issue: https://github.com/Pomax/bezierjs/issues/205

    When you try to find the intersection with a slightly rotated line such as const line = { p1: { x: 400, y: 0 }, p2: { x: 400.01, y: 100 } }, it will work as expected.

    function demo() {
      const controlPoints = [450, 50, 300, 183, 150, 150];
      const line = {
        p1: {
          x: 400,
          y: 0
        },
        p2: {
          x: 400.001,
          y: 100
        }
      };
    
      const intersectionPoints = [];
    
      const [x1, x2, c1, c2, y1, y2] = controlPoints;
      const bezierCurve = new Bezier(x1, x2, Math.floor(c1), Math.floor(c2), y1, y2);
    
      const intersections = bezierCurve.lineIntersects(line);
      if (intersections.length > 0) {
        for (let e = 0; e < intersections.length; e++) {
          let n = intersections[e],
            t = bezierCurve.get(n);
          intersectionPoints.push(t);
        }
      }
    
      console.log("Intersection Points:", intersectionPoints);
    }
    
    document.addEventListener("readystatechange", () => document.readyState === "complete" && demo());
    <script type="module">
      import { Bezier } from 'https://cdn.jsdelivr.net/npm/bezier-js@6.1.4/src/bezier.min.js';
      window.Bezier = Bezier;
    </script>