in packages/maker.js/src/models/BezierCurve.ts [154:216]
function getLargestArc(b: BezierJs.Bezier, startT: number, endT: number, accuracy: number): IPathArcInBezierCurve {
var arc: IPathArc, lastGoodArc: IPathArc;
var start = new TPoint(b, startT);
var end = new TPoint(b, endT);
var upper = end;
var lower = start;
var count = 0;
var test = upper;
var reversed: boolean;
while (count < 100) {
const middle = getIPoint(b.get((start.t + test.t) / 2));
//if the 3 points are linear, this may throw
try {
arc = new paths.Arc(start.point, middle, test.point);
}
catch (e) {
if (lastGoodArc) {
return lastGoodArc as IPath as IPathArcInBezierCurve;
} else {
break;
}
}
//only need to test once to see if this arc is polar / clockwise
if (reversed === undefined) {
reversed = measure.isPointEqual(start.point, point.fromAngleOnCircle(arc.endAngle, arc));
}
//now we have a valid arc, measure the error.
var error = getError(b, startT, test.t, arc, reversed);
//if error is within accuracy, this becomes the lower
if (error <= accuracy) {
(arc as IPath as IPathArcInBezierCurve).bezierData = {
startT: startT,
endT: test.t
};
lower = test;
lastGoodArc = arc;
} else {
upper = test;
}
//exit if lower is the end
if (lower.t === upper.t || (lastGoodArc && (lastGoodArc !== arc) && (angle.ofArcSpan(arc) - angle.ofArcSpan(lastGoodArc)) < .5)) {
return lastGoodArc as IPath as IPathArcInBezierCurve;
}
count++;
test = new TPoint(b, (lower.t + upper.t) / 2);
}
//arc failed, so return a line
var line = new paths.Line(start.point, test.point) as IPath as IPathArcInBezierCurve;
line.bezierData = {
startT: startT,
endT: test.t
};
return line;
}