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