compare XYZ

compare XYZ

jeroen.van.halderen
Advocate Advocate
5,955 Views
4 Replies
Message 1 of 5

compare XYZ

jeroen.van.halderen
Advocate
Advocate

Hi everyone,

 

To determine if a point is in a boundingbox I have to determine if the X, Y and Z coordinate of that point is greater than the min point of the boundingbox and smaller than the max point of the boundingbox. When searching for this I could only find the XYZ.IsAlmostEqualTo() method but there was no method to determine if an XYZ is greater than or smaller than another XYZ.

Did I miss something or are the methods to compare XYZs with the API just a little limited? If so it would be really nice to have the above mentioned comparison methods were added to the API in a later version of Revit.

Thanks in advance!

 

Kind regards,

 

Jeroen van Halderen

0 Likes
Accepted solutions (2)
5,956 Views
4 Replies
Replies (4)
Message 2 of 5

architect.bim
Collaborator
Collaborator
Accepted solution

Hi!

I think such functionality is a bit narrow and unlikely will appear in API. But you can implement it on your own by inheriting the base XYZ class and overloading necessary operators. I am not good enough with C# but in Python it looks like this:

 

class XYZExtended(DB.XYZ):
    def __gt__(self, other):
        if any([self.X < other.X,
                self.Y < other.Y,
                self.Z < other.Z]):
            return False
        return any([self.X > other.X,
                    self.Y > other.Y,
                    self.Z > other.Z])

    def __lt__(self, other):
        if any([self.X > other.X,
                self.Y > other.Y,
                self.Z > other.Z]):
            return False
        return any([self.X < other.X,
                    self.Y < other.Y,
                    self.Z < other.Z])


xyz_1 = XYZExtended()
xyz_2 = XYZExtended(1, 1, 1)
xyz_3 = XYZExtended(-3, -5, -2)

print xyz_1 > xyz_2
print xyz_1 > xyz_3
print xyz_3 < xyz_2

# results
False
True
True

 

 


Maxim Stepannikov | Architect, BIM Manager, Instructor
0 Likes
Message 3 of 5

architect.bim
Collaborator
Collaborator

P.S. The logic of comaring two XYZ objects may be more complex than in the exapmle above, but the main idea is there: overload method, define rules which allow you to say that one object is greater than the other.

Good luck! 😃


Maxim Stepannikov | Architect, BIM Manager, Instructor
0 Likes
Message 4 of 5

jeremy_tammik
Alumni
Alumni
Accepted solution

Thank you for the valid question, and thanks to Maxim for his very helpful answer.

 

Afaik, the correct best practice in .NET is to implement a comparison operator named Compare or a Comparer class:

 

https://duckduckgo.com/?q=.net+comparer

 

Also, since the X, Y and Z coordinates are real values, you need to define a tolerance and add some fuzz to be able to determine equality. 

 

Here is The Building Coder comparer method for XYZ objects:

 

https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/U...

 

 

  /// <summary>
  /// Default tolerance used to add fuzz 
  /// for real number equality detection
  /// </summary>
  public const double _eps = 1.0e-9;

  /// <summary>
  /// Predicate to determine whether the given 
  /// real number should be considered equal to
  /// zero, adding fuzz according to the specified 
  /// tolerance
  /// </summary>
  public static bool IsZero(
    double a,
    double tolerance = _eps )
  {
    return tolerance > Math.Abs( a );
  }

  /// <summary>
  /// Predicate to determine whether the two given 
  /// real numbers should be considered equal, adding 
  /// fuzz according to the specified tolerance
  /// </summary>
  public static bool IsEqual(
    double a,
    double b,
    double tolerance = _eps )
  {
    return IsZero( b - a, tolerance );
  }

  /// <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 )
  {
    int 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;
  }

 

   

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
Message 5 of 5

jeroen.van.halderen
Advocate
Advocate

@jeremy_tammik thank you for your suggestion, I will take a look at it!

0 Likes