Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Handling intersections results when...

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
BenoitE&A
2689 Views, 9 Replies

Handling intersections results when...

BenoitE&A
Collaborator
Collaborator

Hi all,

I want to know how I can handle this very simple case:

Line line1 = Line.CreateBound(new XYZ(), new XYZ(1,0,0));

Line line2 = Line.CreateBound(new XYZ(), new XYZ(2,0,0));

line1.Intersect(line2, out IntersectionResultArray ira);

 

Of course the intersection is the full line1, so I can't do tries like : 

ira.Size

since it does not exist.

 

The idea is to put aside this particular case which has to be handled carefully, while the usual cases (1 intersection or 0 intersection) will be handled in the other parts of my algorithm.

What condition should I use?

Thanks for your ideas!!

Benoit


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
0 Likes

Handling intersections results when...

Hi all,

I want to know how I can handle this very simple case:

Line line1 = Line.CreateBound(new XYZ(), new XYZ(1,0,0));

Line line2 = Line.CreateBound(new XYZ(), new XYZ(2,0,0));

line1.Intersect(line2, out IntersectionResultArray ira);

 

Of course the intersection is the full line1, so I can't do tries like : 

ira.Size

since it does not exist.

 

The idea is to put aside this particular case which has to be handled carefully, while the usual cases (1 intersection or 0 intersection) will be handled in the other parts of my algorithm.

What condition should I use?

Thanks for your ideas!!

Benoit


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
9 REPLIES 9
Message 2 of 10
BenoitE&A
in reply to: BenoitE&A

BenoitE&A
Collaborator
Collaborator

Ok I could not find a simple solution, so... I had to use the bazooka: catch the exception generated by this painfull case.

Line line1 = Line.CreateBound(new XYZ(), new XYZ(1,0,0));

Line line2 = Line.CreateBound(new XYZ(), new XYZ(2,0,0));

line1.Intersect(line2, out IntersectionResultArray ira);

 

            try
            {
                // Try to compute ira.Size

                int size = ira.Size;
            }
            catch (NullReferenceException e)
            {
                // Do what I have to do in this case
            }

 

If anybody has a more elegant solution I am interested!!

 

Interesting side result: the condition

line1.Intersect(line2, out IntersectionResultArray ira)==SetComparisonResult.Overlap

returns false in my case, although there is an obvious intersection result.


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
0 Likes

Ok I could not find a simple solution, so... I had to use the bazooka: catch the exception generated by this painfull case.

Line line1 = Line.CreateBound(new XYZ(), new XYZ(1,0,0));

Line line2 = Line.CreateBound(new XYZ(), new XYZ(2,0,0));

line1.Intersect(line2, out IntersectionResultArray ira);

 

            try
            {
                // Try to compute ira.Size

                int size = ira.Size;
            }
            catch (NullReferenceException e)
            {
                // Do what I have to do in this case
            }

 

If anybody has a more elegant solution I am interested!!

 

Interesting side result: the condition

line1.Intersect(line2, out IntersectionResultArray ira)==SetComparisonResult.Overlap

returns false in my case, although there is an obvious intersection result.


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 3 of 10
dragos.turmac
in reply to: BenoitE&A

dragos.turmac
Autodesk
Autodesk

Hi,

 

You can try to find overlapping lines using the following conditions:

1. The vectors that define them are parallel;

2. Using Curve.Distance(Autodesk.Revit.DB.XYZ), you must check if at least two any Line end points have a 0 distance to the other Curve.

 

e.g.:

// pseudo code

// verify parallelism
Curve a, b;
Vector aV = a.GetEndPoint(1) - a.GetEndPoint(0);
Vector bV = b.GetEndPoint(1) - b.GetEndPoint(0);
if ( aV is not parallel to bV ) exit;

// verify the ends
int matchingEnds = 0;
if ( b.Distance( a.GetEndPoint(0) ) == 0 ) matchingEnds++;
if ( b.Distance( a.GetEndPoint(1) ) == 0 ) matchingEnds++;
if ( a.Distance( b.GetEndPoint(0) ) == 0 ) matchingEnds++;
if ( a.Distance( b.GetEndPoint(1) ) == 0 ) matchingEnds++;

bool overlap = ( matchingEnds == 4 )

What is written above might be a little overkill though since only two verifications should suffice (from each curve verify one end's distance to the other).

Please try to implement above and tell us if this way suits you (beware of tolerances when comparing to 0).



Turmac Dragos
Pr. SW. Engineer
0 Likes

Hi,

 

You can try to find overlapping lines using the following conditions:

1. The vectors that define them are parallel;

2. Using Curve.Distance(Autodesk.Revit.DB.XYZ), you must check if at least two any Line end points have a 0 distance to the other Curve.

 

e.g.:

// pseudo code

// verify parallelism
Curve a, b;
Vector aV = a.GetEndPoint(1) - a.GetEndPoint(0);
Vector bV = b.GetEndPoint(1) - b.GetEndPoint(0);
if ( aV is not parallel to bV ) exit;

// verify the ends
int matchingEnds = 0;
if ( b.Distance( a.GetEndPoint(0) ) == 0 ) matchingEnds++;
if ( b.Distance( a.GetEndPoint(1) ) == 0 ) matchingEnds++;
if ( a.Distance( b.GetEndPoint(0) ) == 0 ) matchingEnds++;
if ( a.Distance( b.GetEndPoint(1) ) == 0 ) matchingEnds++;

bool overlap = ( matchingEnds == 4 )

What is written above might be a little overkill though since only two verifications should suffice (from each curve verify one end's distance to the other).

Please try to implement above and tell us if this way suits you (beware of tolerances when comparing to 0).



Turmac Dragos
Pr. SW. Engineer
Message 4 of 10
BenoitE&A
in reply to: BenoitE&A

BenoitE&A
Collaborator
Collaborator

My previous solution does not work.

The line 

 

int size = ira.Size;

 

returns an exception even when the IntersectionResultArray is empty.

Then I tried to use the property ira.IsEmpty. I got unexpected exceptions and came with the following code :

 

            XYZ pt1 = new XYZ();
            XYZ pt2 = new XYZ(1, 0, 0);
            XYZ pt3 = new XYZ(0, 1, 0);
            XYZ pt4 = new XYZ(1, 1, 0);
            List<Line> liste = new List<Line> { Line.CreateBound(pt1, pt2), Line.CreateBound(pt3, pt4) };
            liste[0].Intersect(liste[1], out IntersectionResultArray ira);
            bool tutu = ira.IsEmpty;

 

When I compute this Revit returns a NullReferenceException. Looks weird to me (what's the use of IsEmpty if it returns an exception when the array is effectedly empty). Any idea?

Anyway I can't find a way to turn this around...


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
0 Likes

My previous solution does not work.

The line 

 

int size = ira.Size;

 

returns an exception even when the IntersectionResultArray is empty.

Then I tried to use the property ira.IsEmpty. I got unexpected exceptions and came with the following code :

 

            XYZ pt1 = new XYZ();
            XYZ pt2 = new XYZ(1, 0, 0);
            XYZ pt3 = new XYZ(0, 1, 0);
            XYZ pt4 = new XYZ(1, 1, 0);
            List<Line> liste = new List<Line> { Line.CreateBound(pt1, pt2), Line.CreateBound(pt3, pt4) };
            liste[0].Intersect(liste[1], out IntersectionResultArray ira);
            bool tutu = ira.IsEmpty;

 

When I compute this Revit returns a NullReferenceException. Looks weird to me (what's the use of IsEmpty if it returns an exception when the array is effectedly empty). Any idea?

Anyway I can't find a way to turn this around...


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 5 of 10
jeremytammik
in reply to: BenoitE&A

jeremytammik
Autodesk
Autodesk

Dear Benoit,

 

Have you looked at the variable `ira` in the debugger?

 

It sounds to me as if it is simply null.

 

So you could check for both:

 

  if( null == ira ) abort
  if ( 0 == ira.Size ) abort

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

Dear Benoit,

 

Have you looked at the variable `ira` in the debugger?

 

It sounds to me as if it is simply null.

 

So you could check for both:

 

  if( null == ira ) abort
  if ( 0 == ira.Size ) abort

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 6 of 10
jeremytammik
in reply to: jeremytammik

jeremytammik
Autodesk
Autodesk

Or better still:

 

  int size = (null==ira) ? 0 : ira.Size;

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes

Or better still:

 

  int size = (null==ira) ? 0 : ira.Size;

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 7 of 10
BenoitE&A
in reply to: jeremytammik

BenoitE&A
Collaborator
Collaborator

Thanks Jeremy, I tried your solution (see code below)

liste[0] and liste[1] are the same (infinite intersection)

liste[0] and liste[2] are parallele (no intersection)

liste[0] and liste[3] are secant (1 intersection)

The result is : 

ira is null in case 1 and 2, and ira.Size = 1 in case 3.

So I can not use this way to distinguish between cases 1 and 2.

 

XYZ pt1 = new XYZ();
            XYZ pt2 = new XYZ(1, 0, 0);
            XYZ pt3 = new XYZ(0, 1, 0);
            XYZ pt4 = new XYZ(1, 1, 0);
            XYZ pt5 = new XYZ(2, 0, 0);
            List<Line> liste = new List<Line> { Line.CreateBound(pt1, pt2), Line.CreateBound(pt3, pt4), Line.CreateBound(pt1, pt5), Line.CreateBound(pt1, pt3) };
            liste[0].Intersect(liste[1], out IntersectionResultArray ira);
            liste[0].Intersect(liste[2], out IntersectionResultArray ira2);
            liste[0].Intersect(liste[3], out IntersectionResultArray ira3);
            int size = (null == ira) ? 0 : ira.Size;
            int size2 = (ira2 == null) ? 0 : ira2.Size;
            try
            {
                monMessage += "\n Empty case, size = "+size;
            }
            catch (NullReferenceException e) // NullReferenceException
            {
                
                monMessage += "\n Empty case exception";
            }
            try
            {
                monMessage += "\n Infinite case, size = " + size2;
            }
            catch (NullReferenceException e)
            {
                monMessage += "\n Infinite case exception";
            }
            monMessage += "\n Finite case, size = " + ira3.Size;


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
0 Likes

Thanks Jeremy, I tried your solution (see code below)

liste[0] and liste[1] are the same (infinite intersection)

liste[0] and liste[2] are parallele (no intersection)

liste[0] and liste[3] are secant (1 intersection)

The result is : 

ira is null in case 1 and 2, and ira.Size = 1 in case 3.

So I can not use this way to distinguish between cases 1 and 2.

 

XYZ pt1 = new XYZ();
            XYZ pt2 = new XYZ(1, 0, 0);
            XYZ pt3 = new XYZ(0, 1, 0);
            XYZ pt4 = new XYZ(1, 1, 0);
            XYZ pt5 = new XYZ(2, 0, 0);
            List<Line> liste = new List<Line> { Line.CreateBound(pt1, pt2), Line.CreateBound(pt3, pt4), Line.CreateBound(pt1, pt5), Line.CreateBound(pt1, pt3) };
            liste[0].Intersect(liste[1], out IntersectionResultArray ira);
            liste[0].Intersect(liste[2], out IntersectionResultArray ira2);
            liste[0].Intersect(liste[3], out IntersectionResultArray ira3);
            int size = (null == ira) ? 0 : ira.Size;
            int size2 = (ira2 == null) ? 0 : ira2.Size;
            try
            {
                monMessage += "\n Empty case, size = "+size;
            }
            catch (NullReferenceException e) // NullReferenceException
            {
                
                monMessage += "\n Empty case exception";
            }
            try
            {
                monMessage += "\n Infinite case, size = " + size2;
            }
            catch (NullReferenceException e)
            {
                monMessage += "\n Infinite case exception";
            }
            monMessage += "\n Finite case, size = " + ira3.Size;


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
Message 8 of 10
jeremytammik
in reply to: BenoitE&A

jeremytammik
Autodesk
Autodesk

Dear Benoit,

 

Thank you for your careful analysis.

 

So, I assume that you are saying that the good news is: no more exception being thrown.

 

At least that problem is now solved, yes?

 

The Revit API cannot implement every method in a manner that optimally suits your needs.

 

In this specific case concerning the exact overlap situation of straight lines, I would suggest implementing the initial classification of exceptional cases such as two lines being the same the same with an infinite intersection or being parallel with no intersection yourself.

 

Tests for these specific conditions are easy to implement and distinguish for straight lines.

 

The IntersectionResult class is rather more general:

 

http://www.revitapidocs.com/2018.1/0b6f0c2e-e3a2-3e27-fa52-0f4f9f2ca6f0.htm

 

This class captures results of intersecting geometric entities. "Intersecting" is meant in generalized sense, so the same class will be used for projection, containment, etc. Refer to the documentation of the method providing the result for the precise meaning of properties.

 

I hope this helps.

 

Sorry that you had to go through all this discussion and research to discover as much as you have!

 

I would love to see what solution you end up implementing to determine the detailed results that you need.

 

That might be useful for others as well.

 

Thank you!

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Dear Benoit,

 

Thank you for your careful analysis.

 

So, I assume that you are saying that the good news is: no more exception being thrown.

 

At least that problem is now solved, yes?

 

The Revit API cannot implement every method in a manner that optimally suits your needs.

 

In this specific case concerning the exact overlap situation of straight lines, I would suggest implementing the initial classification of exceptional cases such as two lines being the same the same with an infinite intersection or being parallel with no intersection yourself.

 

Tests for these specific conditions are easy to implement and distinguish for straight lines.

 

The IntersectionResult class is rather more general:

 

http://www.revitapidocs.com/2018.1/0b6f0c2e-e3a2-3e27-fa52-0f4f9f2ca6f0.htm

 

This class captures results of intersecting geometric entities. "Intersecting" is meant in generalized sense, so the same class will be used for projection, containment, etc. Refer to the documentation of the method providing the result for the precise meaning of properties.

 

I hope this helps.

 

Sorry that you had to go through all this discussion and research to discover as much as you have!

 

I would love to see what solution you end up implementing to determine the detailed results that you need.

 

That might be useful for others as well.

 

Thank you!

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 9 of 10
FAIR59
in reply to: BenoitE&A

FAIR59
Advisor
Advisor
Accepted solution

the return value of the Line.Intersect() method is of class SetComparisonResult. I imagine you can use the return value to distinguish between cases 1 and 2. 

 

 

Return Value

  • SetComparisonResult.Overlap - One or more intersections were encountered. The output argument has the details.
  • SetComparisonResult.Subset - The inputs are parallel lines with only one common intersection point, or the curve used to invoke the intersection check is a line entirely within the unbound line passed as argument curve. If the former, the output argument has the details of the intersection point.
  • SetComparisonResult.Superset - The input curve is entirely within the unbound line used to invoke the intersection check.
  • SetComparisonResult.Disjoint - There is no intersection found between the two curves.
  • SetComparisonResult.Equal - The two curves are identical.
0 Likes

the return value of the Line.Intersect() method is of class SetComparisonResult. I imagine you can use the return value to distinguish between cases 1 and 2. 

 

 

Return Value

  • SetComparisonResult.Overlap - One or more intersections were encountered. The output argument has the details.
  • SetComparisonResult.Subset - The inputs are parallel lines with only one common intersection point, or the curve used to invoke the intersection check is a line entirely within the unbound line passed as argument curve. If the former, the output argument has the details of the intersection point.
  • SetComparisonResult.Superset - The input curve is entirely within the unbound line used to invoke the intersection check.
  • SetComparisonResult.Disjoint - There is no intersection found between the two curves.
  • SetComparisonResult.Equal - The two curves are identical.
Message 10 of 10
BenoitE&A
in reply to: FAIR59

BenoitE&A
Collaborator
Collaborator

Thank you FAIR this should be the solution!!

I say should because there seems to be a problem with subset and superset. Anyway I have my solution since I can exclude case 1 (disjoint) from case 2 (subset or superset) and from case 3 (overlap).

Thank you all for your help!!

 

Here is my code to test subset / superset.

 

            XYZ pt1 = new XYZ();
            XYZ pt2 = new XYZ(1, 0, 0);
            XYZ pt3 = new XYZ(0, 1, 0);
            XYZ pt4 = new XYZ(1, 1, 0);
            XYZ pt5 = new XYZ(2, 0, 0);
            List<Line> liste = new List<Line> { Line.CreateBound(pt1, pt2), Line.CreateBound(pt3, pt4), Line.CreateBound(pt1, pt5), Line.CreateBound(pt1, pt3) };
            SetComparisonResult scr = liste[0].Intersect(liste[1], out IntersectionResultArray ira);
            SetComparisonResult scr2 = liste[0].Intersect(liste[2], out IntersectionResultArray ira2);
            SetComparisonResult scr3 = liste[0].Intersect(liste[3], out IntersectionResultArray ira3);
            SetComparisonResult scr4 = liste[2].Intersect(liste[0], out IntersectionResultArray ira4);
            List<SetComparisonResult> listeSCR = new List<SetComparisonResult> { scr, scr2, scr3 , scr4 };
            for(int i=0; i< listeSCR.Count;i++)
            {
                if (listeSCR[i] == SetComparisonResult.Overlap) monMessage += "\n Case overlap for " + i;
                if (listeSCR[i] == SetComparisonResult.Disjoint) monMessage += "\n Cas disjoint for " + i;
                if (listeSCR[i] == SetComparisonResult.Subset ) monMessage += "\n Case subset for " + i;
                if (listeSCR[i] == SetComparisonResult.Superset) monMessage += "\n Case superset for " + i;
            }

 


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/
0 Likes

Thank you FAIR this should be the solution!!

I say should because there seems to be a problem with subset and superset. Anyway I have my solution since I can exclude case 1 (disjoint) from case 2 (subset or superset) and from case 3 (overlap).

Thank you all for your help!!

 

Here is my code to test subset / superset.

 

            XYZ pt1 = new XYZ();
            XYZ pt2 = new XYZ(1, 0, 0);
            XYZ pt3 = new XYZ(0, 1, 0);
            XYZ pt4 = new XYZ(1, 1, 0);
            XYZ pt5 = new XYZ(2, 0, 0);
            List<Line> liste = new List<Line> { Line.CreateBound(pt1, pt2), Line.CreateBound(pt3, pt4), Line.CreateBound(pt1, pt5), Line.CreateBound(pt1, pt3) };
            SetComparisonResult scr = liste[0].Intersect(liste[1], out IntersectionResultArray ira);
            SetComparisonResult scr2 = liste[0].Intersect(liste[2], out IntersectionResultArray ira2);
            SetComparisonResult scr3 = liste[0].Intersect(liste[3], out IntersectionResultArray ira3);
            SetComparisonResult scr4 = liste[2].Intersect(liste[0], out IntersectionResultArray ira4);
            List<SetComparisonResult> listeSCR = new List<SetComparisonResult> { scr, scr2, scr3 , scr4 };
            for(int i=0; i< listeSCR.Count;i++)
            {
                if (listeSCR[i] == SetComparisonResult.Overlap) monMessage += "\n Case overlap for " + i;
                if (listeSCR[i] == SetComparisonResult.Disjoint) monMessage += "\n Cas disjoint for " + i;
                if (listeSCR[i] == SetComparisonResult.Subset ) monMessage += "\n Case subset for " + i;
                if (listeSCR[i] == SetComparisonResult.Superset) monMessage += "\n Case superset for " + i;
            }

 


Benoit FAVRE
CEO of etudes & automates
www.etudesetautomates.com/

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report