How to select a model line and convert to a curve using C# and Revit 2014

How to select a model line and convert to a curve using C# and Revit 2014

Anonymous
Not applicable
4,939 Views
2 Replies
Message 1 of 3

How to select a model line and convert to a curve using C# and Revit 2014

Anonymous
Not applicable

Im trying to have the user select two lines and I want the Revit API to return the XYZ location of the intersection of those two lines that were selected. So far I have been able to get to the part where the user can select the model lines.

 

Reference referenceLine1 = choices.PickObject(ObjectType.Element,selFilter, "Please select a model line.");

Reference referenceLine2 = choices.PickObject(ObjectType.Element, selFilter, "Please select your other model line.");


Element elementLine1 = doc.GetElement(referenceLine1.ElementId);

Element elementLine2 = doc.GetElement(referenceLine2.ElementId);

 

How to I convert the referenceLine1 object to a Curve class so that I can use the Curve.Intersect method from the revit API to test if two lines intersect?

 

I am trying to do this: 

 

IntersectionResultArray resultArray;

 

SetComparisonResult compareResult = Curve1.Intersect(Curve2);

 

I am pretty sure it involves some type of casting or a "getCurve" method of some sort, but I cannot figure out exactly how.

 

I saw on Jeremy Tammik post that he does this with a line object. If I have a model line, how do I do this with a Model Line that the user has selected? Here is the post where he does this. 

 

http://thebuildingcoder.typepad.com/blog/2010/06/intersection-between-elements.html

 

private XYZ GetIntersection( 
    Line line1, 
    Line line2 )
  {
    IntersectionResultArray results;
 
    SetComparisonResult result 
      = line1.Intersect( line2, out results );
 
    if( result != SetComparisonResult.Overlap )
      throw new InvalidOperationException( 
        "Input lines did not intersect." );
 
    if( results == null || results.Size != 1 )
      throw new InvalidOperationException( 
        "Could not extract line intersection point." );
 
    IntersectionResult iResult 
      = results.get_Item( 0 );
 
    return iResult.XYZPoint;
  }

0 Likes
Accepted solutions (1)
4,940 Views
2 Replies
Replies (2)
Message 2 of 3

hvarjus
Participant
Participant
Accepted solution

I'm not sure if this is easiest way to do that but I think it should work in this way:

 

LocationCurve locationCurve1 = elementLine1.Location as LocationCurve;

LocationCurve locationCurve2 = elementLine2.Location as LocationCurve;

locationCurve1.Curve.Intersect(locationCurve2.Curve);

 

Message 3 of 3

Anonymous
Not applicable

How about this:

 

/// <summary>
/// find the number of intersection points for two segments
/// </summary>
/// <param name="line0">first line</param>
/// <param name="line1">second line</param>
/// <returns>number of intersection points; 0, 1, or 2</returns>
public static int FindIntersection(Line2D line0, Line2D line1)
{
PointF[] intersectPnt = new PointF[2];
return FindIntersection(line0, line1, ref intersectPnt);
}

/// <summary>
/// find the intersection points of two segments
/// </summary>
/// <param name="line0">first line</param>
/// <param name="line1">second line</param>
/// <param name="intersectPnt">0, 1 or 2 intersection points</param>
/// <returns>number of intersection points; 0, 1, or 2</returns>
public static int FindIntersection(Line2D line0, Line2D line1, ref PointF[] intersectPnt)
{
// segments p0 + s * d0 for s in [0, 0], p1 + t * d1 for t in [0, 1]
PointF p0 = line0.StartPnt;
PointF d0 = MathUtil.Multiply(line0.Length, line0.Normal);
PointF p1 = line1.StartPnt;
PointF d1 = MathUtil.Multiply(line1.Length, line1.Normal);

PointF E = MathUtil.Subtract(p1, p0);
float kross = d0.X * d1.Y - d0.Y * d1.X;
float sqrKross = kross * kross;
float sqrLen0 = d0.X * d0.X + d0.Y * d0.Y;
float sqrLen1 = d1.X * d1.X + d1.Y * d1.Y;

// lines of the segments are not parallel
if (sqrKross > MathUtil.Float_Epsilon * sqrLen0 * sqrLen1)
{
float s = (E.X * d1.Y - E.Y * d1.X) / kross;
if (s < 0 || s > 1)
{
// intersection of lines is not point on segment p0 + s * d0
return 0;
}

float t = (E.X * d0.Y - E.Y * d0.X) / kross;
if (t < 0 || t > 1)
{
// intersection of lines is not a point on segment p1 + t * d1
return 0;
}
// intersection of lines is a point on each segment
intersectPnt[0] = MathUtil.Add(p0, MathUtil.Multiply(s, d0));
return 1;
}
// lines of the segments are paralled
float sqrLenE = E.X * E.X + E.Y * E.Y;
float kross2 = E.X * d0.Y - E.Y * d0.X;
float sqrKross2 = kross2 * kross2;
if (sqrKross2 > MathUtil.Float_Epsilon * sqrLen0 * sqrLenE)
{
// lines of the segments are different
return 0;
}

// lines of the segments are the same. need to test for overlap of segments
float s0 = MathUtil.Dot(d0, E) / sqrLen0;
float s1 = s0 + MathUtil.Dot(d0, d1) / sqrLen0;
float smin = MathUtil.GetMin(s0, s1);
float smax = MathUtil.GetMax(s0, s1);
float[] w = new float[2];

int imax = MathUtil.FindIntersection(0.0f, 1.0f, smin, smax, ref w);
for (int i = 0; i < imax; i++)
{
intersectPnt[i] = MathUtil.Add(p0, MathUtil.Multiply(w[i], d0));
}

return imax;
}

0 Likes