Collinear 3D Points

Collinear 3D Points

harilalmn
Advocate Advocate
1,826 Views
8 Replies
Message 1 of 9

Collinear 3D Points

harilalmn
Advocate
Advocate

Hi All,

I know there are mathematical methods to figure out if three 3D points are collinear. Since Revit gives a  method for a line to check  distance to a  point, I just wrote a function as below, assuming p2 is  always lying between p1 and  p3;

 

public bool CollinearPoints(XYZ p1, XYZ p2, XYZ p3)
{
    Line line = Line.CreateBound(p1, p3);
    if (line.Distance(p2) == 0)
    {
        return true;
    }
    return false;
}

 

 Will this be a  reliable approach?

0 Likes
Accepted solutions (3)
1,827 Views
8 Replies
Replies (8)
Message 2 of 9

sahin.ikbal
Advocate
Advocate

Your logic is correct and it will give you what you need but only for very specific situations.
Like, it assumes p2 is in between p1 and p3.
Now if p2 was in a collinear position but it was outside then this logic won't work.
Also its restricted by minimum distance to make a line in revit api.

@harilalmn 

Message 3 of 9

jeremy_tammik
Alumni
Alumni
Accepted solution

Check it out on Wikipedia:

 

https://en.wikipedia.org/wiki/Collinearity

 

I assume that with your method, you wish to check whether the three given points are collinear or not?

 

I cannot comment on your implementation and am unsure wether the built-in Revit API method will provide exactly what you need.

 

I would suggest implementing such a check yourself; it will be more effective and you will know exactly what is going on and why.

 

Here are some solution suggestions:

 

https://www.geeksforgeeks.org/program-check-three-points-collinear/

 

The Building Coder samples already includes a predicate checking for collinear lines:

 

  /// <summary>
  /// Predicate returning true if two given lines are collinear
  /// </summary>
  public static bool IsCollinear( Line a, Line b )
  {
    XYZ v = a.Direction;
    XYZ w = b.Origin - a.Origin;
    return IsParallel( v, b.Direction )
      && IsParallel( v, w );
  }

 

I added a new method to check for collinear points as well:

 

  /// <summary>
  /// Predicate returning true if three given points are collinear
  /// </summary>
  public static bool AreCollinear( XYZ p, XYZ q, XYZ r )
  {
    XYZ v = q - p;
    XYZ w = r - p;
    return IsParallel( v, w );
  }

  

Basically, this method considers the three points as corners of a triangle, determines the vectors from one of them to the two others, and reports whether these two vectors are parallel.

  

Please try it out and let us know whether that satisfies your requirements.

 

Here is the diff to the previous release:

 

https://github.com/jeremytammik/the_building_coder_samples/compare/2022.0.151.0...2022.0.151.1

 

Best regards,

 

Jeremy

 

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

jeremy_tammik
Alumni
Alumni
Accepted solution

A slightly closer look at this including some views on robustness:

 

https://stackoverflow.com/questions/4083807/collinear-points

  

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

jeremy_tammik
Alumni
Alumni
Accepted solution

This one is also good:

 

https://stackoverflow.com/questions/51202034/collinear-points-c

 

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 6 of 9

harilalmn
Advocate
Advocate
Yes the minimum distance is a risk, as you mentioned. I did not think about it. Thanks...!
0 Likes
Message 7 of 9

harilalmn
Advocate
Advocate

@jeremy_tammik 

Thanks for the suggestions and these are  absolutely giving me better and robust solutions.

 

In my case, what I have been trying to do it that I have so many points and I am trying to connect these points with  walls. I will be looping through all the points. Taking three points, currentPoint (say p1), previousPoint (say p0) and nextPoint (say p2), if these three points are collinear, I wont draw a wall from p0 to p1 and skip to the next point, p2. Then I will check if p1, p2 and p3 are collinear. If not, I will draw a  straight wall from p0 to p2, rather than having two segmented walls p0-p1 and p1-p2.

 

I will definitely try out the solutions you have suggested. Thanks for the advise... 

0 Likes
Message 8 of 9

jeremy_tammik
Alumni
Alumni

Are the points you analyse sorted sequentially, or do they come in a random order.

  

For the latter case, a completely different algorithm would be much better suited, for example:

  

https://stackoverflow.com/questions/4557840/find-all-collinear-points-in-a-given-set

  

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

harilalmn
Advocate
Advocate

@jeremy_tammik These points are sequentially sorted. So that is not a problem. In fact they are points which are 'Evaluated' along a curve.

0 Likes