Pomax / bezierjs

A nodejs and client-side library for (cubic) Bezier curve work
MIT License
1.75k stars 235 forks source link

The intersection of the two bezier is empty #203

Open ArtOfOmission opened 1 year ago

ArtOfOmission commented 1 year ago
var tt1 = new Bezier(20.294698715209961, 20.116849899291992,
 26.718513488769531, 28.516490936279297,
 33.345268249511719, 37.4105110168457,
 36.240531921386719,37.736736297607422);
var tt2 = new Bezier(43.967803955078125, 30.767040252685547,
43.967803955078125, 31.771089553833008,
35.013500213623047, 32.585041046142578,
23.967803955078125, 32.585041046142578);
var ttList = tt1.intersects(tt2);

The two bezier curves should intersect, but the result returned is empty, Two bezier curves are marked with red lines in the figure

屏幕截图 2023-07-26 102526

Pomax commented 1 year ago

You're not logging ttList in your console log instruction. You're logging an undefined variable tList. I can highly recommend installing a JS linting extension, or switching your theme, to make sure that undeclared variables are "obviously" highlighted as "this code has a problem even if it'll still run".

justvanrossum commented 1 year ago

I tried earlier, and the snippet (once the tList/ttList typo is fixed) indeed shows an empty result list, despite that the input curves indeed do visually intersect.

ArtOfOmission commented 1 year ago

thanks for the replay,ttList is alse empty.

ArtOfOmission commented 1 year ago

I tried earlier, and the snippet (once the tList/ttList typo is fixed) indeed shows an empty result list, despite that the input curves indeed do visually intersect.

I updated the code

ArtOfOmission commented 1 year ago

You're not logging ttList in your console log instruction. You're logging an undefined variable tList. I can highly recommend installing a JS linting extension, or switching your theme, to make sure that undeclared variables are "obviously" highlighted as "this code has a problem even if it'll still run".

I updated the code. The variable name is wrong, but the ttList is alse empty.

Pomax commented 1 year ago

console logging investigation:

    console.log
      running

      at Bezier.intersects (src/bezier.js:848:13)

    console.log
      curveintersects args:

      at Bezier.curveintersects (src/bezier.js:886:13)

    console.log
      c1 [
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: true,
          _lut: [],
          _t1: 0,
          _t2: 0.05158051653718898,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: false
        },
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: true,
          _lut: [],
          _t1: 0.05158051653718898,
          _t2: 0.05455413371263488,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: false
        }
      ]

      at Bezier.curveintersects (src/bezier.js:887:13)

    console.log
      c2 [
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: false,
          _lut: [],
          _t1: 0,
          _t2: 0.09,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: false
        },
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: false,
          _lut: [],
          _t1: 0.09,
          _t2: 1,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: false
        }
      ]

      at Bezier.curveintersects (src/bezier.js:888:13)

    console.log
      initial pairs []

      at Bezier.curveintersects (src/bezier.js:898:13)

    console.log
      intersections []

      at Bezier.curveintersects (src/bezier.js:913:13)

  ● Intersection testing › https://github.com/Pomax/bezierjs/issues/203
Pomax commented 1 year ago

Looks like the this.reduce() call in intersects yields a curve set that does not span the full [0,1] interval.

Pomax commented 1 year ago
   console.log
      running

      at Bezier.intersects (src/bezier.js:859:13)

    console.log
      first pass reductions: [
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: true,
          _lut: [],
          _t1: 0,
          _t2: 0.05158051653718898,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: false
        },
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: true,
          _lut: [],
          _t1: 0.05158051653718898,
          _t2: 0.05455413371263488,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: false
        },
        Bezier {
          _3d: false,
          points: [ [Object], [Object], [Object], [Object] ],
          order: 3,
          dims: [ 'x', 'y' ],
          dimlen: 2,
          _linear: false,
          _lut: [],
          _t1: 0.05455413371263488,
          _t2: 1,
          dpoints: [ [Array], [Array], [Array] ],
          clockwise: true
        }
      ]

      at Bezier.reduce (src/bezier.js:601:13)

    console.log
      second pass on: Bezier {
        _3d: false,
        points: [
          { x: 20.29469871520996, y: 20.116849899291992 },
          { x: 20.62604239936939, y: 20.550107722706766 },
          { x: 20.95792601544804, y: 20.98468086613082 },
          { x: 21.289809631526694, y: 21.419325704546704 }
        ],
        order: 3,
        dims: [ 'x', 'y' ],
        dimlen: 2,
        _linear: true,
        _lut: [],
        _t1: 0,
        _t2: 0.05158051653718898,
        dpoints: [
          [ [Object], [Object], [Object] ],
          [ [Object], [Object] ],
          [ [Object] ]
        ],
        clockwise: false
      }

      at forEach (src/bezier.js:605:15)
          at Array.forEach (<anonymous>)

    console.log
      t1: 0, t2: 1.0100000000000007

      at forEach (src/bezier.js:629:15)
          at Array.forEach (<anonymous>)

    console.log
      second pass on: Bezier {
        _3d: false,
        points: [
          { x: 21.289809631526694, y: 21.419325704546704 },
          { x: 21.308942724548533, y: 21.44438298282736 },
          { x: 21.328075817570372, y: 21.469440499388 },
          { x: 21.347208807140635, y: 21.49449801594864 }
        ],
        order: 3,
        dims: [ 'x', 'y' ],
        dimlen: 2,
        _linear: true,
        _lut: [],
        _t1: 0.05158051653718898,
        _t2: 0.05455413371263488,
        dpoints: [
          [ [Object], [Object], [Object] ],
          [ [Object], [Object] ],
          [ [Object] ]
        ],
        clockwise: false
      }

      at forEach (src/bezier.js:605:15)
          at Array.forEach (<anonymous>)

    console.log
      t1: 0, t2: 1.0100000000000007

      at forEach (src/bezier.js:629:15)
          at Array.forEach (<anonymous>)

    console.log
      second pass on: Bezier {
        _3d: false,
        points: [
          { x: 21.347208807140635, y: 21.494498015948643 },
          { x: 27.430441729082755, y: 29.46140298519073 },
          { x: 33.50321685100052, y: 37.42830795443282 },
          { x: 36.24053192138672, y: 37.73673629760742 }
        ],
        order: 3,
        dims: [ 'x', 'y' ],
        dimlen: 2,
        _linear: false,
        _lut: [],
        _t1: 0.05455413371263488,
        _t2: 1,
        dpoints: [
          [ [Object], [Object], [Object] ],
          [ [Object], [Object] ],
          [ [Object] ]
        ],
        clockwise: true
      }

      at forEach (src/bezier.js:605:15)
          at Array.forEach (<anonymous>)
Pomax commented 1 year ago
    console.log
      second pass on: Bezier {
        _3d: false,
        points: [
          { x: 21.347208807140635, y: 21.494498015948643 },
          { x: 27.430441729082755, y: 29.46140298519073 },
          { x: 33.50321685100052, y: 37.42830795443282 },
          { x: 36.24053192138672, y: 37.73673629760742 }
        ],
        order: 3,
        dims: [ 'x', 'y' ],
        dimlen: 2,
        _linear: false,
        _lut: [],
        _t1: 0.05455413371263488,
        _t2: 1,
        dpoints: [
          [ [Object], [Object], [Object] ],
          [ [Object], [Object] ],
          [ [Object] ]
        ],
        clockwise: true
      }

      at forEach (src/bezier.js:605:15)
          at Array.forEach (<anonymous>)

    console.log
      dead segment for t1:0 and t2:0

Looks like the second pass in the reduction function needs some proper debugging.

Undistraction commented 4 months ago

@Pomax I think I'm seeing the same problem. intersect will correctly detect the intersection most of the time, but occasionally returns an empty array. The most minute change in one of the curves can result in no intersections, and happens for cases where the intersection is obvious between two curves that simply cross (i.e. intersections aren't end points, and curves don't cross multiple times). I can provide an interactive page that will allow to easily replicate the issue if that would be helpful.