IntersectWith() with plane in third argument

IntersectWith() with plane in third argument

Anonymous
Not applicable
6,532 Views
28 Replies
Message 1 of 29

IntersectWith() with plane in third argument

Anonymous
Not applicable

Hello, 

 

 

I have to use the method IntersectWith() with 3d entities that have different Z, i need to calculate the intersection points.

 

i think to use the following method to calculate the intersection points : 

 

 

thisEntity.IntersectWith(otherEntity,Intersect.OnBothOperands, new Plane(), points, thisGraphicSystemMarker, otherGraphicSystemMarker)

Can you tell me if thisEntity can be a 3d polylines and otherEntity a polyline means that they have deffent Z ?

can i get a get a plane from the polyline(otherEntity) to use it as the third argument ?

the result is a collection of Points2d or Points3d ?

 

i need that the result be a Points3dcollection with the Z of the first entity!! is that possible.

 

 

0 Likes
Accepted solutions (1)
6,533 Views
28 Replies
Replies (28)
Message 2 of 29

_gile
Consultant
Consultant

Hi,

 

To learn something, you should make your own tests.

 

        [CommandMethod("TEST")]
        public void Test()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var opts = new PromptEntityOptions("\nSelect polyline (2d or 3d): ");
            opts.SetRejectMessage("\nSelected object is not a polyline.");
            opts.AddAllowedClass(typeof(Polyline), true);
            opts.AddAllowedClass(typeof(Polyline3d), true);

            var result = ed.GetEntity(opts);
            if (result.Status != PromptStatus.OK)
                return;
            var thisEntityId = result.ObjectId;

            result = ed.GetEntity(opts);
            if (result.Status != PromptStatus.OK)
                return;
            var otherEntityId = result.ObjectId;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var thisEntity = (Entity)tr.GetObject(thisEntityId, OpenMode.ForRead);

                var otherEntity = (Entity)tr.GetObject(otherEntityId, OpenMode.ForRead);

                var intersPts = new Point3dCollection();
                var plane = new Plane(); // new Plane(Point3d.Origin, Vector3d.ZAxis);

                thisEntity.IntersectWith(otherEntity, Intersect.OnBothOperands, plane, intersPts, IntPtr.Zero, IntPtr.Zero);
                ed.WriteMessage("\nUsing new Plane()");
                foreach (Point3d pt in intersPts)
                {
                    ed.WriteMessage("\n{0}", pt); 
                }

                if (thisEntity is Polyline)
                {
                    intersPts.Clear();
                    plane = ((Polyline)thisEntity).GetPlane();
                    thisEntity.IntersectWith(otherEntity, Intersect.OnBothOperands, plane, intersPts, IntPtr.Zero, IntPtr.Zero);
                    ed.WriteMessage("\nUsing thisEntity.GetPlane())");
                    foreach (Point3d pt in intersPts)
                    {
                        ed.WriteMessage("\n{0}", pt);
                    }
                }

                if (otherEntity is Polyline)
                {
                    intersPts.Clear();
                    plane = ((Polyline)otherEntity).GetPlane();
                    thisEntity.IntersectWith(otherEntity, Intersect.OnBothOperands, plane, intersPts, IntPtr.Zero, IntPtr.Zero);
                    ed.WriteMessage("\nUsing otherEntity.GetPlane()");
                    foreach (Point3d pt in intersPts)
                    {
                        ed.WriteMessage("\n{0}", pt);
                    }
                }

                tr.Commit();
            }
            Application.DisplayTextScreen = true;
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 3 of 29

ActivistInvestor
Mentor
Mentor

@_gile shows an example of how to project the intersection points onto either of the two entities planes, but it might be worth noting that you can be more generic when intersecting between any two types of Entity, by first checking each entity's IsPlanar property, and if true, getting its plane using GetPlane().

 

Also, In the case of using the intersection points with GetSplitCurves() you generally want to use the Plane of the curve that you call IntersectWith() on, because the intersection points will be projected back into that entity's plane, and so you must then call GetSplitCurves() on the same curve, because it requires the resulting points to lie on that curve.

 

 

0 Likes
Message 4 of 29

Anonymous
Not applicable

You did great work for me...
Thank you very much...

0 Likes
Message 5 of 29

Anonymous
Not applicable

Thank you very much, you understand my issue... 

 

regards.

0 Likes
Message 6 of 29

Anonymous
Not applicable

@ActivistInvestor what can i do if the entity isn't Planar to get intersection points!!!

0 Likes
Message 7 of 29

ActivistInvestor
Mentor
Mentor
Accepted solution

@Anonymous wrote:

@ActivistInvestor what can i do if the entity isn't Planar to get intersection points!!!


The method below will take the intersection points, and the Plane of the clipping boundary curve/polyline, and will return an array of parameters that you can pass to the GetSplitCurves() method. You call IntersectWith() on each Curve you want to clip, and then pass the resulting points to this method, along with the Curve you want to clip in the first argument and the Plane of the clipping boundary entity in the last argument.

 

/// <summary>
/// Returns the parameters of the supplied points, optionally projected onto 
/// the curve along the direction defined by the normal of the Plane argument. 
/// 
/// The resulting parameters are ordered by their position on the curve.
/// 
/// If the plane argument is null, the supplied points must lie on the curve.
/// </summary>
/// <param name="curve">The Curve instance</param>
/// <param name="points">The sequence of points whose parameters are to be computed</param>
/// <param name="plane">The plane whose normal the points are projected along</param>
/// <returns>The parameters ordered by position along the curve</returns>
 

public static double[] GetSplitParameters(Curve curve, Point3dCollection points, Plane plane = null)
{
   // Assert.IsNotNull(curve, "curve");
   // Assert.IsNotNull(points, "points");
   int count = points.Count;
   if(count == 0)
      return new double[0];
   double[] parameters = new double[count];
   if(plane != null)
   {
      Vector3d normal = plane.Normal;
      for(int i = 0; i < count; i++)
         parameters[i] = curve.GetParameterAtPoint(curve.GetClosestPointTo(points[i], normal, false));
   }
   else
   {
      for(int i = 0; i < count; i++)
         parameters[i] = curve.GetParameterAtPoint(points[i]);
   }
   Array.Sort(parameters);
   return parameters;
}

 

Message 8 of 29

Anonymous
Not applicable

@ActivistInvestor thank you very much for your reply,

 

i tested to get the intersection points in the plane of the entity to split which is a polyline even if it isn't planar with the boundary and use these points in GetSplitCurves(), the split worked very well. 

 

 but  i can't get the intersection points in the plane of the entity to split to use it in this method because it isn't planar to get its plane using GetPlane()

0 Likes
Message 9 of 29

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

@ActivistInvestor thank you very much for your reply,

 

i tested to get the intersection points in the plane of the entity to split wich is a polyline even if it isn't planar with the boundary and use these points in GetSplitCurves(), the split worked very well. 

 

 but  i can't get the intersection points in the plane of the entity to split to use it in this method because it isn't planar to get its plane using GetPlane()


The plane of the entity you are going to split is not the plane you want the intersection points in. You want the intersection points in the plane of the clipping boundary (which must be a planar Curve). The code I posted will take those points and project them onto the curve that you want to split, which is what GetSplitCurves() requires.

 

Pseudo code:

 

Curve boundary = ...    // the planar clipping boundary
Curve entityToClip = ... // the curve to be clipped
Point3dCollection points = new Point3dCollection()
boundary.IntersectWith(entityToClip, Intersect.OnBothOperands, boundary.GetPlane(), points, IntPtr.Zero, IntPtr.Zero); double[] parameters = GetSplitParameters(entityToClip, points, boundary.GetPlane()); var curves = entityToClip.GetSplitCurves(new DoubleCollection(parameters));

 

Message 10 of 29

Anonymous
Not applicable

I am very grateful, thank you very much...

0 Likes
Message 11 of 29

Anonymous
Not applicable

@ActivistInvestor  i need your help please the split work very well when the entities ares not closed, but if the entity is a closed Polyline3d the it is devided  not only at intersection points with the boundary but also in other points on the curve. i don't know if the problem is in the following method : 

 

 

public static double[] GetSplitParameters(Curve curve, Point3dCollection points, Plane plane = null)
{
   // Assert.IsNotNull(curve, "curve");
   // Assert.IsNotNull(points, "points");
   int count = points.Count;
   if(count == 0)
      return new double[0];
   double[] parameters = new double[count];
   if(plane != null)
   {
      Vector3d normal = plane.Normal;
      for(int i = 0; i < count; i++)
         parameters[i] = curve.GetParameterAtPoint(curve.GetClosestPointTo(points[i], normal, false));
   }
   else
   {
      for(int i = 0; i < count; i++)
         parameters[i] = curve.GetParameterAtPoint(points[i]);
   }
   Array.Sort(parameters);
   return parameters;
} 
0 Likes
Message 12 of 29

Anonymous
Not applicable

@ActivistInvestor for example i have a closed polyline3d, the number of intersection points is 2, the number of parameters result of the method :

GetSplitParameters()

 is 2  but i get 3 parts from the split ! what is normal is obtaining two parts !... the polyline3d was devided not only at the boundary but at other points also, even if it was closed. 

0 Likes
Message 13 of 29

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

@ActivistInvestor for example i have a closed polyline3d, the number of intersection points is 2, the number of parameters result of the method :

GetSplitParameters()

 is 2  but i get 3 parts from the split ! what is normal is obtaining two parts !... the polyline3d was devided not only at the boundary but at other points also, even if it was closed. 


if you break a polyline at two points, neither of which is at an end, how many polylines do expect to have?

0 Likes
Message 14 of 29

Anonymous
Not applicable

do you mean that i will have 3 parts using the end point, even if it is closed ? 😞 how can i ignore the split in the end point or connect parts within the boundary ? other than getting vertices and generating one polyline.

0 Likes
Message 15 of 29

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

do you mean that i will have 3 parts using the end point, even if it is closed ? 😞 how can i ignore the split in the end point or connect parts within the boundary ? other than getting vertices and generating one polyline.


It could be a bug, but GetSplitCurves() on a closed, 3d polyline will always create one additional segment, that starts at the start point of the 3d polyline. I can't tell you why it works that way.

 

You would have to join the adjacent segments on the side of the boundary that you are not clipping away. You can try calling the JoinEntities() method on the segment that starts at the original 3d polyline's start point, and pass it the other segments on the same side of the clipping boundary.

Message 16 of 29

Anonymous
Not applicable

Hello, thank you very much, I solved the previous problem by the JoinEntity () method, but I found another problem that is the intersection points are 2 but the splitting is done at a single point of intersection and 2 other points Specific to the polygon, saying that one of these two points is the end point, what is the other point?

0 Likes
Message 17 of 29

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

Hello, thank you very much, I solved the previous problem by the JoinEntity () method, but I found another problem that is the intersection points are 2 but the splitting is done at a single point of intersection and 2 other points Specific to the polygon, saying that one of these two points is the end point, what is the other point?


It should not matter what the other point is if the split curves are all connected at their endpoints.

 

You would have to join the segments or not join them.

0 Likes
Message 18 of 29

Anonymous
Not applicable

yes, but for some entities i d'don't have the split at the two points of intersection just at one! 

0 Likes
Message 19 of 29

ActivistInvestor
Mentor
Mentor

@Anonymous wrote:

yes, but for some entities i d'don't have the split at the two points of intersection just at one! 


 

You can't make those kind of assumptions.

 

You have to check the result of GetSplitCurves() to see what's there. The number of curves can depend on how many intersections there are, and on whether the entity that is split is a closed 3d polyline.  So, you have no choice but to check it always.

0 Likes
Message 20 of 29

Anonymous
Not applicable

 

 

I didn't make any assumptions i got these problems as a result for some entities, my only assumption is that the split will be at the two points of intrsection and the end of the 3d polyline closed, but i found that for some entities, the splitting is done at a single point of intersection and 2 other points Specific to the polygon, saying that one of these two points is the end point, what is the other point ?  

 

 

0 Likes