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
Solved! Go to Solution.
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
Solved! Go to Solution.
Solved by FAIR59. Go to Solution.
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.
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.
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).
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).
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...
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...
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
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
Or better still:
int size = (null==ira) ? 0 : ira.Size;
Cheers,
Jeremy
Or better still:
int size = (null==ira) ? 0 : ira.Size;
Cheers,
Jeremy
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;
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;
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
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
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.
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.
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;
}
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;
}
Can't find what you're looking for? Ask the community or share your knowledge.