hello so im having a trouble with this i have a list (static) to save location of a placed family instance . when i check if the location of the family instance exists in the list i get false even thos the location exists in the list help me plz
Hi!
In your case I think it is more proper to use IsAlmostEqualTo method of XYZ class. You can also specify tolerance if it is needed.
Hi @Houba3314 ,
I am able to reproduce the issue you mentioned.
Thank you @architect.bim .
You can try using the below sample code
private void SimpleCode()
{
XYZ p1 = new XYZ(0, 0, 0);
XYZ p2 = new XYZ(10, 0, 0);
IList<XYZ> points = new List<XYZ>();
points.Add(p1);
points.Add(p2);
//I think you are using this sample code
//You are facing the issue here
if(points.Contains(new XYZ(10,0,0)))
{
}
//My suggestion is to use the below sample code
if (string.Join("",points).Contains(new XYZ(10,0,0).ToString()))
{
//Yes, the code inside this if loop will be executed.
}
//Test - Add more points
XYZ p3 = new XYZ(10, 10, 0);
points.Add(p3);
if (string.Join("", points).Contains(new XYZ(10, 10, 0).ToString()))
{
//Yes, the code inside this if loop will be executed.
}
}
you couldn't compare XYZ with another XYZ mathematically , as it is not logic
however there is another round about way,
you can transfer the XYZ point to string then compare the 2 string together ,
XYZ p1 = new XYZ(0,0,0) ;
string p1_s = p1.tostring();
if (p1_s == p2_s)
{
}
You can create a new class to compare point use IComparable
void Main()
{
double x1 = 10;
double y1 = 10;
double z1 = 10;
double x2 = 10;
double y2 = 10;
double z2 = 10;
var point1 = new ComparePoint(x1,y1,z1);
var point2 = new ComparePoint(x2,y2,z2);
// case equal
var result = point1.CompareTo(point2);
// if equal return 0
// if less than return negative value
// if greater than return positive value
Console.WriteLine(result);
}
public class ComparePoint : IComparable<ComparePoint>
{
public double x { get; }
public double y { get; }
public double z { get; }
public ComparePoint(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public int CompareTo(ComparePoint other)
{
if (other == null) return 1;
if (x.CompareTo(other.x) != 0)
{
return x.CompareTo(other.x);
}
else if (y.CompareTo(other.y) != 0)
{
return y.CompareTo(other.y);
}
else if (z.CompareTo(other.z) != 0)
{
return z.CompareTo(other.z);
}
else
{
return 0;
}
}
}
Chuong Ho
For points I usually just compare via XYZ.DistanceTo given a specific tolerance value i.e. reduce it to a 1D problem.
Similarly for vectors I usually use DotProduct but it is all subjective and more to do with what you decide for yourself is appropriate for two things to be considered the same.
Doubles are notoriously difficult to compare since they have rounding differences that are compounded with repetitive arithmetic operations (so you have to compare to an epsilon). Also certain numerical values that the structure finds hard to represent lead to greater such issues. I often think I could ultimately convert to fractions of a mm as the whole number and use Int64 for comparisons.
Int64.MaxValue | e.g. | Int32.MaxValue | e.g. |
9223372036854770000 | μm | 2147483647 | mm |
9223372036854770 | mm | 2147484 | m |
9223372036855 | m | 2147 | km |
9223372037 | km |
This scope is doubled when accounting for the negative space.
Nobody has a project that size in Revit i.e. 214 km measured to a tenth of a mm for Int32.
You can implement a standard Compare method for XYZ that fits into the .NET generic collection paradigm like this:
/// <summary>
/// Comparison method for two real numbers
/// returning 0 if they are to be considered equal,
/// -1 if the first is smaller and +1 otherwise
/// </summary>
public static int Compare(
double a,
double b,
double tolerance = _eps)
{
return IsEqual(a, b, tolerance)
? 0
: a < b
? -1
: 1;
}
/// <summary>
/// Comparison method for two XYZ objects
/// returning 0 if they are to be considered equal,
/// -1 if the first is smaller and +1 otherwise
/// </summary>
public static int Compare(
XYZ p,
XYZ q,
double tolerance = _eps)
{
var d = Compare(p.X, q.X, tolerance);
if (0 == d)
{
d = Compare(p.Y, q.Y, tolerance);
if (0 == d) d = Compare(p.Z, q.Z, tolerance);
}
return d;
}
You can pass in this Compare method to all .NET generic list searching, sorting and dictionary key comparison mechanisms. Many The Building Coder samples and articles illustrate its use.