bezierjs
bezierjs copied to clipboard
`simple` does not behave correctly on edge case
The simple function has a minor issue in edge cases where the start and end point normals are equal, such as when constructing a bezier curve for a straight line. The issue appears to arise due to limits of floating point.
The simple function has the following snippet to compute the angle between endpoint normals
var n1 = this.normal(0);
var n2 = this.normal(1);
var s = n1.x*n2.x + n1.y*n2.y;
if(this._3d) { s += n1.z*n2.z; }
var angle = abs(acos(s));
The snippet is mathematically correct, but in practice when n1 = n2 the variable s is computed with finite precision and can fall just outside the domain of the acos function and cause it to return NaN. As an example If I construct a cubic bezier curve from the points (1,1), (2,2), (3,3) and (4,4) we have n1 = n2 and then we have s = 1.0000000000000002, and finally angle = NaN. All comparisons with NaN return false in javascript (and most other languages) and so the function incorrectly returns false.
I believe the issue is remedied if we simply clamp s to the interval [-1, 1] as one would never expect a dot product between unit vectors to be outside this range.
The issue can cause unnecessary splitting of straight lines in the reduce function.