Remove colinear vertices polyline

Remove colinear vertices polyline

MGO-Norsyn
Advocate Advocate
2,526 Views
12 Replies
Message 1 of 13

Remove colinear vertices polyline

MGO-Norsyn
Advocate
Advocate

Hi everybody.

I was searching for a method to remove colinear vertices from polyline today and couldn't find any thing readily available, so I had to write my own and I want to share this method with anybody needing it in the future.

 

 

public static void RemoveColinearVerticesPolyline(Polyline pline)
{
	List<int> verticesToRemove = new List<int>();

	for (int i = 0; i < pline.NumberOfVertices - 1; i++)
	{
		SegmentType st1 = pline.GetSegmentType(i);
		SegmentType st2 = pline.GetSegmentType(i + 1);
		if (st1 == SegmentType.Line && st1 == st2)
		{
			LineSegment2d ls2d1 = pline.GetLineSegment2dAt(i);
			LineSegment2d ls2d2 = pline.GetLineSegment2dAt(i + 1);

			if (ls2d1.IsColinearTo(ls2d2)) verticesToRemove.Add(i + 1);
		}
	}

	verticesToRemove.Reverse();
	pline.UpgradeOpen();
	for (int j = 0; j < verticesToRemove.Count; j++)
		pline.RemoveVertexAt(verticesToRemove[j]);
}

 

0 Likes
Accepted solutions (1)
2,527 Views
12 Replies
Replies (12)
Message 2 of 13

_gile
Consultant
Consultant

Hi,

Here's an example which works with linera and coincident segments.

        public static void RemoveColinearVerticesPolyline(Polyline pline)
        {
            for (int i = 0; i < pline.NumberOfVertices - 1; i++)
            {
                if (pline.GetSegmentType(i) == SegmentType.Coincident)
                {
                    pline.RemoveVertexAt(i + 1);
                    i--;
                }
                else if (pline.GetSegmentType(i) == SegmentType.Line)
                {
                    var seg1 = pline.GetLineSegment2dAt(i);
                    switch (pline.GetSegmentType(i + 1))
                    {
                        case SegmentType.Line:
                            if (pline.GetLineSegment2dAt(i + 1).IsColinearTo(seg1))
                            {
                                pline.RemoveVertexAt(i + 1);
                                i--;
                            }
                            break;
                        case SegmentType.Coincident:
                            pline.RemoveVertexAt(i + 1);
                            i--;
                            break;
                        default:
                            break;
                    }
                }
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 13

_gile
Consultant
Consultant
Accepted solution

This one also deals with concentric arc segments.

        public static void RemoveColinearVerticesPolyline(Polyline pline)
        {
            for (int i = 0; i < pline.NumberOfVertices - 1; i++)
            {
                if (pline.GetSegmentType(i) == SegmentType.Coincident)
                {
                    pline.RemoveVertexAt(i);
                    i--;
                }
                else if (pline.GetSegmentType(i) == SegmentType.Line)
                {
                    var segment = pline.GetLineSegment2dAt(i);
                    switch (pline.GetSegmentType(i + 1))
                    {
                        case SegmentType.Line:
                            if (pline.GetLineSegment2dAt(i + 1).IsColinearTo(segment))
                            {
                                pline.RemoveVertexAt(i + 1);
                                i--;
                            }
                            break;
                        case SegmentType.Coincident:
                            pline.RemoveVertexAt(i + 1);
                            i--;
                            break;
                        default:
                            break;
                    }
                }
                else if (pline.GetSegmentType(i) == SegmentType.Arc)
                {
                    var segment = pline.GetArcSegment2dAt(i);
                    switch (pline.GetSegmentType(i + 1))
                    {
                        case SegmentType.Arc:
                            var nextSegment = pline.GetArcSegment2dAt(i + 1);
                            if (segment.Center.IsEqualTo(nextSegment.Center) && 
                                segment.IsClockWise == nextSegment.IsClockWise)
                            {
                                double bulge = Math.Tan(
                                    Math.Atan(pline.GetBulgeAt(i)) +
                                    Math.Atan(pline.GetBulgeAt(i + 1)));
                                pline.RemoveVertexAt(i + 1);
                                pline.SetBulgeAt(i, bulge);
                                i--;
                            }
                            break;
                        case SegmentType.Coincident:
                            pline.RemoveVertexAt(i + 1);
                            i--;
                            break;
                        default:
                            break;
                    }
                }
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 13

MGO-Norsyn
Advocate
Advocate

Hi, thanks for you input, I am sure it will be useful for someone in the future. 😉

I have one question though, I have not tested your methods, but does it really work with polyline's vertices being deleted when iterating over them? I tried that in my method first, but it messed up the vertice's numbers so it was not correct.

I solved it by gathering vertice numbers, then reversing the list with numbers, then removing the vertices starting with the highest number vertice first, så it wouldn't mess up the iteration.

But I see you do the removing the vertices up front and it really works?

0 Likes
Message 5 of 13

_gile
Consultant
Consultant

Test it and you'll see it really works...



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 13

_gile
Consultant
Consultant

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 13

MGO-Norsyn
Advocate
Advocate
Great!
0 Likes
Message 8 of 13

MGO-Norsyn
Advocate
Advocate

Here is my take on removing collinear vertices on a Polyline3d:

 

 

PromptEntityOptions peo = new PromptEntityOptions("\nSelect pline 3d: ");
                    peo.AddAllowedClass(typeof(Polyline3d), true);
PromptEntityResult per = editor.GetEntity(peo);
Polyline3d pline = per.ObjectId.Go<Polyline3d>(tx);

List<int> verticesToRemove = new List<int>();

PolylineVertex3d[] vertices = pline.GetVertices(tx);

for (int i = 0; i < vertices.Length - 2; i++)
{
	PolylineVertex3d vertex1 = vertices[i];
	PolylineVertex3d vertex2 = vertices[i + 1];
	PolylineVertex3d vertex3 = vertices[i + 2];

	Vector3d vec1 = vertex1.Position.GetVectorTo(vertex2.Position);
	Vector3d vec2 = vertex2.Position.GetVectorTo(vertex3.Position);

	if (vec1.IsCodirectionalTo(vec2, Tolerance.Global)) verticesToRemove.Add(i + 1);
}

Point3dCollection p3ds = new Point3dCollection();

for (int i = 0; i < vertices.Length; i++)
{
	if (verticesToRemove.Contains(i)) continue;
	PolylineVertex3d v = vertices[i];
	p3ds.Add(v.Position);
}

Polyline3d nyPline = new Polyline3d(Poly3dType.SimplePoly, p3ds, false);
nyPline.AddEntityToDbModelSpace(localDb);

nyPline.Layer = pline.Layer;

pline.CheckOrOpenForWrite();
pline.Erase(true);

 

 

0 Likes
Message 9 of 13

bcddss
Enthusiast
Enthusiast
Hi. You can attach the dll file because not everyone has a visual studio to build the dll file. Thank you
Ahags
0 Likes
Message 10 of 13

kerry_w_brown
Advisor
Advisor

@bcddss wrote:
Hi. You can attach the dll file because not everyone has a visual studio to build the dll file. Thank you

With due respect :

This is a peer to peer programming support group, NOT a shopping center.


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
Message 11 of 13

bcddss
Enthusiast
Enthusiast
I understand that this peer-to-peer programming support group focuses on providing guidance and assistance rather than directly sharing files. Thank you for your assistance. My bad, sorry for inconvenience.
Ahags
0 Likes
Message 12 of 13

kibitotato
Advocate
Advocate

HOW CAN I USE THIS. I M USED TO USE LISP BUT NOT THIS.

0 Likes
Message 13 of 13

Ed__Jobe
Mentor
Mentor

@kibitotato wrote:

HOW CAN I USE THIS. I M USED TO USE LISP BUT NOT THIS.


You have to learn C# and the .NET api or you can translate this to lisp. Take a look at the (vlax-curve-????) functions.

 

BTW, typing in all caps is like yelling.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes