Repository: FreeCAD/FreeCAD
File: src/Mod/Sketcher/Gui/DrawSketchHandlerArcOfEllipse.h (C/C++)

Code before:
            // Display radius for user
            if (showCursorCoords()) {
                SbString text;
                std::string aString = lengthToDisplayFormat(a, 1);
                std::string bString = lengthToDisplayFormat(b, 1);
                text.sprintf(" (R%s, R%s)", aString.c_str(), bString.c_str());
                setPositionText(onSketchPos, text);
            }

            drawEdit(EditCurve);
            seekAndRenderAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f));
        }
        else if (Mode == STATUS_SEEK_Fourth) {  // here we differ from ellipse creation
            Base::Vector2d delta12 = axisPoint - centerPoint;

            double a = delta12.Length();
            // if a is 0 the ellipse is degenerate

            Base::Vector2d aDir = delta12.Normalize();
            Base::Vector2d bDir(-aDir.y, aDir.x);

            Base::Vector2d delta13 = startingPoint - centerPoint;
            Base::Vector2d delta13Prime(
                delta13.x * aDir.x + delta13.y * aDir.y,
                delta13.x * bDir.x + delta13.y * bDir.y
            );

            double cosT = max(-1.0, min(1.0, delta13Prime.x / a));
            double sinT = sqrt(max(0.0, 1 - cosT * cosT));
            // if sinT is 0 the ellipse is degenerate

            double b = abs(delta13Prime.y) / sinT;

            startAngle = atan2(delta13Prime.y / b, delta13Prime.x / a);

            Base::Vector2d delta14 = onSketchPos - centerPoint;
            Base::Vector2d delta14Prime(
                delta14.x * aDir.x + delta14.y * aDir.y,
                delta14.x * bDir.x + delta14.y * bDir.y
            );
            double angle1 = atan2(delta14Prime.y / b, delta14Prime.x / a) - startAngle;
            double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * pi;

            arcAngle = abs(angle1 - arcAngle) < abs(angle2 - arcAngle) ? angle1 : angle2;

            for (int i = 0; i < 34; i++) {
                double angle = startAngle + i * arcAngle / 33.0;
                double rx1 = a * cos(angle) * aDir.x + b * sin(angle) * bDir.x;
                double ry1 = a * cos(angle) * aDir.y + b * sin(angle) * bDir.y;
                EditCurve[i] = Base::Vector2d(centerPoint.x + rx1, centerPoint.y + ry1);
            }

Review comment (suggestion):
Since it's possible for `a` to be zero here this line is pretty fragile (if `delta13Prime.x` is zero you're going to get a NaN). It's probably advisable to handle the degenerate case explicitly. Same goes for `sinT` and `b`.

Code after:
            if (showCursorCoords()) {
                SbString text;
                std::string aString = lengthToDisplayFormat(a, 1);
                std::string bString = lengthToDisplayFormat(b, 1);
                text.sprintf(" (R%s, R%s)", aString.c_str(), bString.c_str());
                setPositionText(onSketchPos, text);
            }

            drawEdit(EditCurve);
            seekAndRenderAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f));
        }
        else if (Mode == SelectMode::Fourth) {  // here we differ from ellipse creation
            Base::Vector2d delta12 = axisPoint - centerPoint;

            double a = delta12.Length();

            Base::Vector2d aDir = delta12.Normalize();
            Base::Vector2d bDir(-aDir.y, aDir.x);

            Base::Vector2d delta13 = startingPoint - centerPoint;
            Base::Vector2d delta13Prime(
                delta13.x * aDir.x + delta13.y * aDir.y,
                delta13.x * bDir.x + delta13.y * bDir.y
            );

            double cosT = max(-1.0, min(1.0, delta13Prime.x / a));
            double sinT = sqrt(max(0.0, 1 - cosT * cosT));

            double b = abs(delta13Prime.y) / sinT;

            startAngle = atan2(delta13Prime.y / b, delta13Prime.x / a);

            Base::Vector2d delta14 = onSketchPos - centerPoint;
            Base::Vector2d delta14Prime(
                delta14.x * aDir.x + delta14.y * aDir.y,
                delta14.x * bDir.x + delta14.y * bDir.y
            );
            double angle1 = atan2(delta14Prime.y / b, delta14Prime.x / a) - startAngle;
            double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * pi;

            arcAngle = abs(angle1 - arcAngle) < abs(angle2 - arcAngle) ? angle1 : angle2;

            for (int i = 0; i < 34; i++) {
                double angle = startAngle + i * arcAngle / 33.0;
                double rx1 = a * cos(angle) * aDir.x + b * sin(angle) * bDir.x;
                double ry1 = a * cos(angle) * aDir.y + b * sin(angle) * bDir.y;
                EditCurve[i] = Base::Vector2d(centerPoint.x + rx1, centerPoint.y + ry1);
            }

            // Display radii and angle for user
            if (showCursorCoords()) {