TryFitCircleTTT Bug

Hi,
I’ve been struggling to know what is causing TryFitCircleTTT to generate a Circle on top of the previous one I created.

I attatch the example scene and the command for you to test.

(It seems to happen only when I have aligned curves in some axis, for example, if I move up (z) the Second Curve 0.001 units, It will work as expected, and it creates a Circle next to the other).

TryFitCircle_Bug_ExampleScene.3dm (220.9 KB)

              public class TestTryFitCircleTTT : Command

{
public override string EnglishName => “TestTryFitCircleTTT”;

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
    Curve curve1;
    Curve curve2;
    Curve curve3;
    Point3d[] points = new Point3d[3];

    var getCurve = new GetObject { GeometryAttributeFilter = GeometryAttributeFilter.OpenCurve | GeometryAttributeFilter.ClosedCurve };
    getCurve.SetCommandPrompt("Select 2 curves");
    var getCurvesResult = getCurve.GetMultiple(3,3);
    if (getCurvesResult != Rhino.Input.GetResult.Object)
        return Result.Cancel;
    curve1 = getCurve.Objects()[0].Curve();
    curve2 =  getCurve.Objects()[1].Curve();
    curve3 =  getCurve.Objects()[2].Curve();

    var getPoint = new GetPoint();
    for (int i = 0; i < 3; i++)
    {
        getPoint.SetCommandPrompt("Select point");
        getPoint.AcceptNothing(false);
        getPoint.Get();
        if (getPoint.CommandResult() != Result.Success)
            break;
        points[i] = getPoint.Point();
    }

    // THIS DOES NOT WORK
    double param1 = 3.1415926535897913;
    double param2 = 14.091276059207669;
    double param3 = 14.09127605920767;

    // THIS WORKS
    curve1.ClosestPoint(points[0], out param1); // Output param1 = 3.1415926535897931
    curve2.ClosestPoint(points[1], out param2); // Output param2 = 14.091276059207669
    curve3.ClosestPoint(points[2], out param3); // Output param3 = 14.091276059207669
    Circle outCircle = Circle.TryFitCircleTTT(curve1, curve2, curve3, param1, param2, param3);

    doc.Objects.AddCircle(outCircle);
    doc.Views.Redraw();

    return Result.Success;
}

Increases a bit (0.2 or 0.5) the param1, param2 and param3. Or even beter, get the parameters using the closest point of an approximation circle center point.

The problem is, that if I get the parameters using the ClosestPoint of the points that are in the scene I provided, those parameters work and creates the circle I want. (And the double numbers are nearly the same)

I don’t say that, but create an approximation center, like moving the center of the first curve along the two big curves, and use that point to get the proper parameters.

:thinking:

No idea what do you mean with that.

I mean that if the last digits of a double are different, it gives a very different result. Which it shouldn’t.

I already did the circle aproximation to get the points that are in the scene. And I got about 99% cases working except when the Second and Third curves are perfectly aligned, that is when it fails.

    public class TestTryFitCircleTTT : Command
{
    public override string EnglishName => "TestTryFitCircleTTT";

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        Curve curve1;
        Curve curve2;
        Curve curve3;
        Point3d[] points = new Point3d[3];

        var getCurve = new GetObject { GeometryAttributeFilter = GeometryAttributeFilter.OpenCurve | GeometryAttributeFilter.ClosedCurve };
        getCurve.SetCommandPrompt("Select 2 curves");
        var getCurvesResult = getCurve.GetMultiple(3,3);
        if (getCurvesResult != Rhino.Input.GetResult.Object)
            return Result.Cancel;
        curve1 = getCurve.Objects()[0].Curve();
        curve2 =  getCurve.Objects()[1].Curve();
        curve3 =  getCurve.Objects()[2].Curve();

        var getPoint = new GetPoint();
        for (int i = 0; i < 3; i++)
        {
            getPoint.SetCommandPrompt("Select point");
            getPoint.AcceptNothing(false);
            getPoint.Get();
            if (getPoint.CommandResult() != Result.Success)
                break;
            points[i] = getPoint.Point();
        }

        // THIS DOES NOT WORK
        double param1 = 3.1415926535897913;
        double param2 = 14.091276059207669;
        double param3 = 14.09127605920767;

        // THIS WORKS
        curve1.ClosestPoint(points[0], out param1); // Output param1 = 3.1415926535897931
        curve2.ClosestPoint(points[1], out param2); // Output param2 = 14.091276059207669
        curve3.ClosestPoint(points[2], out param3); // Output param3 = 14.091276059207669
        Circle outCircle = Circle.TryFitCircleTTT(curve1, curve2, curve3, param1, param2, param3);

        doc.Objects.AddCircle(outCircle);
        doc.Views.Redraw();

        return Result.Success;
    }
}