I have been struggling with a strange issue. I applied an inset along the binormal direction of a series of curves and some of the binormal directions are randomly flipping causing strange anomalies. I have isolated a few of the curves in an image below. Red represents the start of the curve and blue is the end.

Any ideas? I am assuming there is some floating point error occurring, most likely during one of the cross product computations, or perhaps when the rotation matrix is being applied to the normal vector. I just want to make sure I am not making any silly mistakes.

// inset method on custom class which has the curve as a property.
inset(inset){
const [count, closed] = [this.curve.points.length, this.closed];
const frames = this.curve.computeFrenetFrames(count, closed);
const points = this.curve.getSpacedPoints(count);
this.curve.points = points.map((point, index) => {
// _n_vec is defined in the global scope of the module
_n_vec.copy(frames.binormals[index]).negate().multiplyScalar(inset);
return point.add(_n_vec);
})
}

So the real issue I am having (as I suspected) is my own stupidity. I forgot that I had re-clocked the curves after they were inset so that the start/ends all lined up. When I disabled the clocking this is what each curve looked like. The anomaly is always the last point.

The issue seems to stem from the fact that I was directly assigning the spaced points back to the original points. Since the curve is closed it creates another point at the end. So every time I did…

It was appending another point to the end of the curve at the exact same location (+/- floating point error). This was messing up the tangent calculations at the end. So in my inset method I just had to pop the last point and everything worked fine.

inset(inset){
const [count, closed] = [this.curve.points.length, this.closed];
const frames = this.curve.computeFrenetFrames(count, closed);
const points = this.getSpacedPoints(count);
// console.log(points.length, count) // shows that points.length === count + 1
points.forEach((point, index) => {
_n_vec.copy(frames.binormals[index]).negate().multiplyScalar(inset);
point.add(_n_vec);
})
if(closed) points.pop(); // need to remove the last point
this.curve.points = points;
}