AutoCAD .NET has exposed two tolerance constants (Tolerance.Global.EqualPoint & Tolerance.Global.EqualVector) for us to use when necessary. In this article, let’s focus o the Tolerance.Global.EqualPoint.
What is the real value for the Tolerance.Global.EqualPoint and how may it be used in the convenient AutoCAD .NET API Point3d.IsEqualTo()?
The following code/command makes it clear.
[CommandMethod("Tolerance_Test")]
public static void Tolerance_Test_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Database db = HostApplicationServices.WorkingDatabase;
try
{
ed.WriteMessage("\nTolerance.Global.EqualPoint: {0}\nTolerance.Global.EqualVector: {1}", Tolerance.Global.EqualPoint, Tolerance.Global.EqualVector);
//Tolerance.Global.EqualPoint: 1E-10
//Tolerance.Global.EqualVector: 1E-12
Point3d pt0 = new Point3d(1, 1, 1);
Point3d pt1 = new Point3d(1 + Tolerance.Global.EqualPoint, 1 + Tolerance.Global.EqualPoint, 1 + Tolerance.Global.EqualPoint);
Point3d pt2 = new Point3d(1 + Tolerance.Global.EqualPoint / 2, 1 + Tolerance.Global.EqualPoint / 2, 1 + Tolerance.Global.EqualPoint / 2);
Point3d pt3 = new Point3d(1 + Tolerance.Global.EqualPoint / 2, 1, 1);
Point3d pt4 = new Point3d(1 + Tolerance.Global.EqualPoint / 5, 1, 1);
Point3d pt5 = new Point3d(1, 1, 1 + Tolerance.Global.EqualPoint / 10);
Point3d pt6 = new Point3d(1, 1, 1 - Tolerance.Global.EqualPoint / 5);
Point3d pt7 = new Point3d(1, 1, 1 - Tolerance.Global.EqualPoint + Tolerance.Global.EqualVector);
Point3d pt8 = new Point3d(1 + Tolerance.Global.EqualPoint, 1, 1);
Point3d pt9 = new Point3d(1, 1, 1 - Tolerance.Global.EqualPoint);
double ourDist9 = Math.Sqrt((pt9.X - pt0.X) * (pt9.X - pt0.X) + (pt9.Y - pt0.Y) * (pt9.Y - pt0.Y) + (pt9.Z - pt0.Z) * (pt9.Z - pt0.Z));
ed.WriteMessage("\nDist1(pt0 to pt1): {0}\tEqual? {1}", pt0.DistanceTo(pt1), pt0.IsEqualTo(pt1));
ed.WriteMessage("\nDist2(pt0 to pt2): {0}\tEqual? {1}", pt0.DistanceTo(pt2), pt0.IsEqualTo(pt2));
ed.WriteMessage("\nDist3(pt0 to pt3): {0}\tEqual? {1}", pt0.DistanceTo(pt3), pt0.IsEqualTo(pt3));
ed.WriteMessage("\nDist4(pt0 to pt4): {0}\tEqual? {1}", pt0.DistanceTo(pt4), pt0.IsEqualTo(pt4));
ed.WriteMessage("\nDist5(pt0 to pt5): {0}\tEqual? {1}", pt0.DistanceTo(pt5), pt0.IsEqualTo(pt5));
ed.WriteMessage("\nDist6(pt0 to pt6): {0}\tEqual? {1}", pt0.DistanceTo(pt6), pt0.IsEqualTo(pt6));
ed.WriteMessage("\nDist7(pt0 to pt7): {0}\tEqual? {1}", pt0.DistanceTo(pt7), pt0.IsEqualTo(pt7));
ed.WriteMessage("\nDist8(pt0 to pt8): {0}\tEqual? {1}", pt0.DistanceTo(pt8), pt0.IsEqualTo(pt8));
ed.WriteMessage("\nDist9(pt0 to pt9): {0}\tEqual? {1}", pt0.DistanceTo(pt9), pt0.IsEqualTo(pt9));
ed.WriteMessage("\nOur Dist9(pt0 to pt9): {0}\tEqual? {1}", ourDist9, ourDist9 <= Tolerance.Global.EqualPoint);
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
Here is the command output.
Command: Tolerance_Test
Tolerance.Global.EqualPoint: 1E-10
Tolerance.Global.EqualVector: 1E-12
Dist1(pt0 to pt1): 1.7320509508794E-10 Equal? False
Dist2(pt0 to pt2): 8.66025475439702E-11 Equal? True
Dist3(pt0 to pt3): 5.00000041370186E-11 Equal? True
Dist4(pt0 to pt4): 2.00000016548074E-11 Equal? True
Dist5(pt0 to pt5): 1.00000008274037E-11 Equal? True
Dist6(pt0 to pt6): 2.00000016548074E-11 Equal? True
Dist7(pt0 to pt7): 9.90000303957572E-11 Equal? True
Dist8(pt0 to pt8): 1.00000008274037E-10 Equal? False
Dist9(pt0 to pt9): 1.00000008274037E-10 Equal? False
Our Dist9(pt0 to pt9): 1.00000008274037E-10 Equal? False
So likely, as also hinted from the documentation about the “Tolerance Structure” topic, the Point3d.IsEqualTo() method calculates out the distance between the two points first and compares it with the Tolerance.Global.EqualPoint next (which is 1E-10 as verified by the above code and output).
“Two points, p1 and p2, are equal if
(p1 - p2).length() <= equalPoint”
By the way, since the Point3d.DistanceTo(Point3d) and the Point3d.IsEqualTo(Point3d) AutoCAD .NET APIs have been provided for long time, we don't have to revent or copy something. We’d better forget about the above equation regarding point equality comparison, which may or may not be consistent with what has been (or will be) applied in AutoCAD itself. If things are consistent there, we are all good; if not or things change in the future, we will get inconsistent results here and there now and then in our own programs.
In fact, according to the IEEE standard, the double type value can hold around 16 decimal digits in whatever computer languages such as C/C++, Java, C#, VB.NET, Perl, Python, and so on, but AutoCAD chooses to use a less precise system, 10 decimal digits for the point tolerance and 12 decimal digits for the vector tolerance. It seems using 15 decimal digits or the tolerance of 1E-15 is safe enough nowadays.
The Tolerance.Global.EqualPoint can still be used to compare length (or single double value) for example in our programs. However, it seems sometimes we’d better use a looser tolerance such as 1E-8 or 1E-6 to give users more flexibilities but sometimes the same tolerance as (or maybe even tighter than) what AutoCAD uses such as in the case of the Curve.IsOn, the Curve.GetClosestPointTo() and the Curve.GetParameterAtPoint that we talked about previously.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Posted by: |