Pomax / bezierjs

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

Floating point rounding error causes bug in Bezier.simple() #187

Open stoarca opened 1 year ago

stoarca commented 1 year ago

Here's a test case:

let bezier = new Bezier(
  {
    "x": 14.187262535095215,
    "y": 8.270401954650879
  },
  {
    "x": 14.179354667663574,
    "y": 8.262494087219238
  },
  {
    "x": 14.179354667663574,
    "y": 8.262494087219238
  },
  {
    "x": 14.171446800231934,
    "y": 8.254586219787598
  }
);
let ret = bezier.reduce();
console.log(ret);

I expect ret to be non-empty. The bug is in Bezier.simple():

image

This can be fixed by clamping s between -1 and 1.

Pomax commented 1 year ago

That's not a rounding error. That's literally how IEEE floats work, but clamping is still a good idea.

stoarca commented 1 year ago

by "rounding error" i was referring to the possible delta between the IEEE result and the exact mathematical result https://en.wikipedia.org/wiki/Round-off_error