Hi,
Can someone clarify me the meaning of these two IntersectionResult members in plain words?
i understand that SetComparisonResult.Overlap is returned when a real intersevtion is exists
but how do i know if the intersection is on the extents of the curves or when it is on one curve?
thanks, Moshe
Solved! Go to Solution.
Solved by Moshe-A. Go to Solution.
As I understand it the normalized parameter has its value scaled relative to the length of the curve, so that a point laying at one end will have a value of 0 and a point at the other end will have a value of 1. If a point lies outside of the extents it will either have a negative value or a value greater than 1.
Unnormalized parameters are based on some arbitrary point without any scaling, there is no way of knowing if a parameter lies within the curve extents unless you either normalise it using ComputeNormalizedParameter(), or manually compare it against the values returned by GetEndParameter() for each end of the curve.
So, to answer your question.
To check whether the intersection point lies on a particular curve, take the corresponding parameter from the UV object (U for first curve, V for second), normalize it to the respective curve and then check whether its value is between 0 and 1.
Also I think from memory there is a method for the Face class called something like PointIsOnFace() (probably completely wrong by you get the idea) that checks whether a given UV point lies within the face boundaries. I can't be sure whether the Curve class has a similar method, but take a quick look and see if it does, it might be a simpler method.
My description might not be 100% accurate as I rarely use Revit's curve geometry methods (I use my own line and plane geometry library) but I'm sure it's enough for you to investigate further and confirm for yourself.
I just looked up the API docs for the Curve class and there is a method called IsInside(). You pass in an un-normalised parameter (either U or V from the IntersectionResult.UVPoint property) and it will report whether the point is within the bounds.
I think that will meet your requirements.
Scott hi,
sorry i did not had the time to check this out untill now
As far as i can see if there is not intersection the IntersectionResultArray returns null which makes it unrelevent in case the intersection is on the extents of the curves
and i would like to know if there is any intersection between the two curves even if it is on the extents of each other or both?
Moshe
I'm not sure I understand what you mean. I just notice that you mentioned SetComparisonResult.Overlap in your original post, are you trying to find intersecting curves or curve segments that are colinear / overlapping?
Scott,
i'm sure you are familier with the (intersect) function of AutoLISP or the method (vlr-intersectwith) of VisualLISP
does curve.intersect() have a similer performance?
Moshe
Sorry, in my earlier comments I was under the wrong assumption of how the Intersect method behaved and have probably confused the situation a little. I don't use this part of the API much and in my own geometry library I treat the curves as unbound for calculating the intersections and then provide a method for later checking whether an intersection is actually within a curve's extents. This is how I assumed Revit also behaved, as it returns unnormalized parameters and provides methods such as IsInside(). It doesn't work that way though.
I did a little research and I now understand that Revit's Intersect method takes into account whether each curve is set as Bound or Unbound and calculates the intersection accordingly. This means that if you operate on curves that are bound, you will only get intersections that exist within the bounds of those curves. This is similar to AutoLISP's (inters <pt1><pt2><pt3><pt4>[<onseg>]) function when the 5th parameter (onseg) is either missing or set >0. It's a little more flexible though, in that you can test intersections between combinations of bound and unbound curves.
The inters function also allows you the option to treat the lines as infinite (onseg = nil) so that out-of-bounds intersections can be found. Unfortunately, Revit doesn't seem to have have a similar method for this. If you want to do this in Revit, you'll need to convert bound curves to unbound using Curve.MakeUnbound() before testing them. The problem is that MakeUnbound() modifies the curve in-place, which isn't ideal unless you are using a throw away dataset than can be manipulated for this purpose. You will probably want to make a copy of each curve and then convert the copies to unbound before testing, which seems like a bit of a pain to me.
An API method such as Curve.GetUnbound() that returns a new unbound copy of the curve while leaving teh original unchanged would be quite beneficial I think. Curve.IntersectAsUnbound(Curve) or even an overload of the original function with a switch would also be nice.
If someone knows of a better method to check the unbound intersections of bound curves, or I am still wrong in my understanding, please set the record straight.
Scott,
i tried to give a shot to curve.MakeUnbound() method but it turns out that my curve object turn to read only after running this code
ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Lines);
Autodesk.Revit.DB.View pView = ActiveUIDocument.Document.ActiveView;
FilteredElementCollector collector = new FilteredElementCollector(ActiveUIDocument.Document, pView.Id);
IList<Element> LineCollection = collector.WherePasses(filter).WhereElementIsNotElementType().ToElements();
ModelCurve modelCurve = LineCollection[0] as ModelCurve;
Curve curve = modelCurve.GeometryCurve;
curve.MakeUnbound(); // throw exception curve is read only
and didn't found the way to set it read/write
i am deeply stuck with this
thanx
Moshe
For read-only curves, you will need to create a new matching curve using the appropriate .CreateBound() method of the underlying Curve object (Line, Arc, etc.) and then call .MakeUnbound() on the new copy. See what I mean about it being a pain...
I'm not sure if there is an easy API supported method of creating a deep copy of a curve object, but here's a quick example of the kind of tasks that are needed to do it manually.
Curve boundLineCurve = Some curve you have obtained Line curveAsLine = boundLineCurve as Line; if(curveAsLine != null) { Curve unboundLineCurveA = Line.CreateBound(curveAsLine.GetEndPoint(0), curveAsLine.GetEndPoint(1)); unboundLineCurveA.MakeUnbound();
// Alternate more direct method Curve unboundLineCurveB = Line.CreateUnbound(curveAsLine.GetEndPoint(0), curveAsLine.Direction); unboundLineCurveA.Intersect(...); } else { Check another Curve type such as arc and do similar }
wow Scott,
that works, thank you very much for this
i understand this not ideal but at least i have some solusion to start with
Moshe