function getLargestArc()

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;
    }