.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

how to split a polyline at its self intersection points

9 REPLIES 9
Reply
Message 1 of 10
eriannanda
7601 Views, 9 Replies

how to split a polyline at its self intersection points

hi,

 

I'm trying to split a polyline that have some intersection points at its intersection points. So, if a polyline have two self intersection point, then it will become three different polyline. I attach the example of a polyline that I want to split. I wonder, does the get split curve method can help me to do this ? or any other idea how can I do this ?

 

I'm new to .net programming so I still don't know how some methods works

thanks

9 REPLIES 9
Message 2 of 10
adam.nagy
in reply to: eriannanda

Hi,

 

Yes, GetSplitCurves() could be useful as it can split the polyline, however you have to provide the additional logic that will be able to turn the polyline you attached into 3 closed loop polylines. Depending on which vertex is the start/end point of the polyline you'll get different results.

 

Another thing that might be useful for you to know is that there is a boundary tracing function available since AutoCAD 2011. In AutoCAD 2011 only in the ARX API (I think), but in 2012 it is also available under Editor.TraceBoundary(). If you specify a point that fals inside a loop then it will give you the poly loop around that point. In previous versions you could use the -BOUNDARY command instead.

 

In both cases though first you'd probably have to figure out the intersection points. So you would need to iterate through each segment of the poly and try to intersect it with all the other segments. Depending on the return value of Polyline.GetSegmentType() you would need to call either GetLineSegmentAt or GetArcSegmentAt. These segments then provide an IntersectWith function that you can use.

 

I hope this helps.

 

Cheers,

Adam Nagy

Autodesk Developer Network 



Adam Nagy
Autodesk Platform Services
Message 3 of 10
eriannanda
in reply to: adam.nagy

hi,

 

yes, I found out that there is no simple way to do that, that I have to provide the additional logic to split the polyline

I'm still working on it

 

thanks for your answer !

 

Message 4 of 10
junoj
in reply to: adam.nagy

Thank Adam for the post.

Message 5 of 10

Hi

 

Did you find anything regarding your concers ?

 I have to do exact same. if possible can you share code.

 

Thanks in advanse.

Message 6 of 10
SENL1362
in reply to: nimesh.patel298

Simplified version, not tested for special types of intersections.

After splitting Create Region is added to show results.

 

 

        [CommandMethod("SPAI")]
        public static void SplitPolylineAtIntersection()
        {
            Document doc = null;
            Database db = null;
            Editor ed = null;


            try
            {
                doc = AcadApp.DocumentManager.MdiActiveDocument;
                if (doc == null)
                    throw new System.Exception("No MdiActiveDocument");
                db = doc.Database;
                ed = doc.Editor;

                var plPeo = new PromptEntityOptions("Select Poly");
                var per = ed.GetEntity(plPeo);
                if (per.Status != PromptStatus.OK)
                    return;
                var plId = per.ObjectId;




                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    var ms = (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite);
                    var pl = tr.GetObject(plId, OpenMode.ForRead) as Polyline;

                    var plSegs = new DBObjectCollection();
                    pl.Explode(plSegs);

                    //Test each Poly Segment for intersection with the other segments.
                    //These segments will be splitted at the intersections and tested again
                    int i = -1;
                    while (++i < plSegs.Count)
                    {
                        var segi = plSegs[i] as Curve;
                        if (segi == null) continue;

                        int j = -1;
                        while (++j < plSegs.Count)
                        {
                            if (j == i) continue;
                            var segj = plSegs[j] as Curve;
                            if (segj == null) continue;

                            //Test Segment[i] against Segment[j]
                            Point3dCollection intsPnts = new Point3dCollection();
                            segi.IntersectWith(segj, Intersect.OnBothOperands, intsPnts, IntPtr.Zero, IntPtr.Zero);
                            if (intsPnts.Count > 0)
                            {
                                var splCurves = segi.GetSplitCurves(intsPnts);
                                if (splCurves.Count > 1)  //don't add curves splitted at the start or end
                                {
                                    foreach (DBObject splCurve in splCurves)
                                    {
                                        plSegs.Add(splCurve);
                                        //for testing purposes add segments to database
                                        ms.AppendEntity((Entity)splCurve);
                                        tr.AddNewlyCreatedDBObject(splCurve, true);
                                    }
                                    plSegs[i] = null;
                                    break; //exit while j, next i
                                }
                            }
                        }
                    }
                    pl.UpgradeOpen();
                    pl.Erase();

                    //for testing purposes add remaning segments to database
                    // add the not splitted segments to the Database
                    foreach (DBObject plseg in plSegs)
                    {
                        if (plseg == null) continue;
                        if (plseg.ObjectId.IsNull)
                        {
                            ms.AppendEntity((Entity)plseg);
                            tr.AddNewlyCreatedDBObject(plseg, true);
                        }
                    }

                    //Create regions from splitted segments
                    // then create closed polylines from these regions
                    var regions=Region.CreateFromCurves(plSegs);

                    //for testing purposes add regions to database
                    foreach (DBObject region in regions)
                    {
                        ms.AppendEntity((Entity)region);
                        tr.AddNewlyCreatedDBObject(region, true);
                    }

                    tr.Commit();
                }
            }
            catch (System.Exception ex)
            {
                if (ed != null)
                    ed.WriteMessage("\n Error in SplitPolylineAtIntersection: {0}", ex.Message);
            }
        }

Screenshot_1.png

 

Screenshot_2.png

 

 

 

 

 

 

 

 

 

 

Message 7 of 10
BKSpurgeon
in reply to: adam.nagy

I would add the following to Adam's post: http://through-the-interface.typepad.com/through_the_interface/2010/06/tracing-a-boundary-defined-by...

 

which is a good example of the trace boundary implmentation.

 

best rgds,

BK

Message 8 of 10
BKSpurgeon
in reply to: eriannanda

I do not complete understand what you are trying to do, but if you are happy to click three different times, within each of the separate triangles, then trace boundary sounds ok. but if you want a programatically complete solution, perhaps investigate the code kindly posted by the other user.

 

best rgds

 

BK

Message 9 of 10
silke.foernzler
in reply to: SENL1362

The above algorithm for splitting polylines works quite nice... until the polyline contains arc segments that will be splitted.

To handle this problem, just add the following lines of code after the call to 'IntersectWith()':

 

for (int k = intsPnts.Count-1; k >= 0; k--)
{
   Point3d pt = intsPnts[k];
   if (FuzzyEquals(pt, segi.StartPoint) || FuzzyEquals(pt, segi.EndPoint))
      intsPnts.RemoveAt(k);
}

 

Best regards,

Silke

Message 10 of 10
sllana
in reply to: silke.foernzler

why so complicated? just use "bo" (boundary) command, use generate pline and pick a point and pick inner points in every polygon you want a region.

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

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost