Author Topic: Distance and azimuth between vertices of a polyline in c#  (Read 4883 times)

0 Members and 1 Guest are viewing this topic.

rodrigo_gcmsoft

  • Guest
Distance and azimuth between vertices of a polyline in c#
« on: April 05, 2011, 03:23:31 PM »
I have a routine in C # that lists all the vertices of a polyline. I wonder how the distance between each vertex and what angle to the y-axis of the drawing. Anyone have any ideas?


CODE:

Code: [Select]
[CommandMethod("listaVertices")]
static public void ListVertices()
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database db = doc.Database;
PromptEntityResult per = ed.GetEntity("Select a polyline");
if (per.Status == PromptStatus.OK)
{
Transaction tr = db.TransactionManager.StartTransaction();
using (tr)
{
DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
// If a "lightweight" (or optimized) polyline
Polyline lwp = obj as Polyline;
if (lwp != null)
{
// Use a for loop to get each vertex, one by one
int vn = lwp.NumberOfVertices;
for (int i = 0; i < vn; i++)
{
// Could also get the 3D point here
Point2d pt = lwp.GetPoint2dAt(i);
ed.WriteMessage("\n" + pt.ToString());
}
}
else
{
// If an old-style, 2D polyline
Polyline2d p2d = obj as Polyline2d;
if (p2d != null)
{
// Use foreach to get each contained vertex
foreach (ObjectId vId in p2d)
{
Vertex2d v2d = (Vertex2d)tr.GetObject(vId, OpenMode.ForRead);
ed.WriteMessage("\n" + v2d.Position.ToString());
}
}
else
{
// If an old-style, 3D polyline
Polyline3d p3d = obj as Polyline3d;
if (p3d != null)
{
// Use foreach to get each contained vertex
foreach (ObjectId vId in p3d)
{
PolylineVertex3d v3d = (PolylineVertex3d)tr.GetObject(vId, OpenMode.ForRead);
ed.WriteMessage("\n" + v3d.Position.ToString());
}
}
}
}
// Committing is cheaper than aborting
tr.Commit();
}
}
}



Thanks!

Rodrigo

bieres

  • Guest
Re: Distance and azimuth between vertices of a polyline in c#
« Reply #1 on: April 05, 2011, 04:46:10 PM »
I do not speak English,
I misunderstood what you want, I attached the modified code, where you calculate the distance between the points and the angle from the x axis.

No hablo ingles,
No he entendido bien lo que quieres, te adjunto el codigo modificado, donde te calcula la distancia entre los puntos y el angulo respecto al eje X.
Para la polyline3d haz algo parecido.


Code: [Select]
[CommandMethod("listaVertices")]
        static public void ListVertices()
         {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            PromptEntityResult per = ed.GetEntity("Select a polyline");
            if (per.Status == PromptStatus.OK)
            {
                Transaction tr = db.TransactionManager.StartTransaction();
                using (tr)
                {
                    DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForRead);
                    // If a "lightweight" (or optimized) polyline
                    Polyline lwp = obj as Polyline;
                    if (lwp != null)
                    {
                        // Use a for loop to get each vertex, one by one
                        int vn = lwp.NumberOfVertices;
                        for (int i = 0; i < vn; i++)
                        {
                            // Could also get the 3D point here
                            Point2d pt = lwp.GetPoint2dAt(i);
                            ed.WriteMessage("\n" + pt.ToString());
                            Point2d pt2d;
                            if (i != 0)
                            {
                                double d =Math.Round(pt.GetDistanceTo(pt2d),2);
                                string s = d.ToString("\n" + "0.00" +  " m.");
                                ed.WriteMessage(s);
                                double ang= pt2d.GetVectorTo(pt).Angle;
                                s = ang.ToString("\n" + "0.00");
                                ed.WriteMessage(s);
                                pt2d = pt;
                            }
                            else
                            {
                                pt2d= pt;
                            }
                        }
                    }
                    else
                    {
                        // If an old-style, 2D polyline
                        Polyline2d p2d = obj as Polyline2d;
                        if (p2d != null)
                        {
                            // Use foreach to get each contained vertex
                            foreach (ObjectId vId in p2d)
                            {
                                Vertex2d v2d = (Vertex2d)tr.GetObject(vId, OpenMode.ForRead);
                                ed.WriteMessage("\n" + v2d.Position.ToString());
                            }
                        }
                        else
                        {
                            // If an old-style, 3D polyline
                            Polyline3d p3d = obj as Polyline3d;
                            if (p3d != null)
                            {
                                // Use foreach to get each contained vertex
                                foreach (ObjectId vId in p3d)
                                {
                                    PolylineVertex3d v3d = (PolylineVertex3d)tr.GetObject(vId, OpenMode.ForRead);
                                    ed.WriteMessage("\n" + v3d.Position.ToString());
                                }
                            }
                        }
                    }
                    // Committing is cheaper than aborting
                    tr.Commit();
                }
            }
        }

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Distance and azimuth between vertices of a polyline in c#
« Reply #2 on: April 05, 2011, 05:17:41 PM »
Hi

Look at the Polyline.GetLineSegmentAt() method wich returns a LineSegment3d object which has a Length and a Direction properties.
Speaking English as a French Frog

fixo

  • Guest
Re: Distance and azimuth between vertices of a polyline in c#
« Reply #3 on: April 06, 2011, 08:35:06 AM »
@Rodrigo
I'm not sure I've calculated the azimuths right
chech it by yourself (snip):
 
Code: [Select]
public static double rtd(double a)
        {
            return a * 180 / Math.PI;
        }
// If a "lightweight" (or optimized) polyline
                    Polyline lwp = obj as Polyline;
                    if (lwp != null)
                    {
                        StringBuilder sb = new StringBuilder();
                        Point2d pt0 = lwp.GetPoint2dAt(0);
                        sb.Append(string.Format("X = {0:f3}\tY = {1:f3}\n", pt0.X, pt0.Y));
                        // Use a for loop to get each vertex, one by one
                        int vn = lwp.NumberOfVertices;
                        for (int i = 0; i < vn; i++)
                        {

                            // Could also get the 3D point here
                            if (lwp.GetSegmentType(i) == SegmentType.Line)
                            {
                                LineSegment2d lws = lwp.GetLineSegment2dAt(i);
                                Point2d pt = lws.EndPoint;
                                Vector2d vec = lws.Direction;
                                double ang = vec.Angle;

                                double azimuth = new double();
                               
                                if (ang == 0)
                                {
                                    azimuth = 90.0;
                                }
                                else
                                {
                                    if (ang > 0 && ang < Math.PI / 2)
                                    {
                                        azimuth = 90 - rtd(ang);
                                    }
                                    else
                                    {
                                        if (ang == Math.PI / 2)
                                        {
                                            azimuth = 0.0;
                                        }
                                        else
                                        {
                                            if (ang > Math.PI / 2 && ang < Math.PI)
                                            {
                                                azimuth = rtd(ang) + 180;
                                            }
                                            else
                                            {
                                                if (ang == Math.PI)
                                                {
                                                    azimuth = 270.0;
                                                }
                                                else
                                                {
                                                    if (ang > Math.PI && ang < Math.PI * 1.5)
                                                    {
                                                        azimuth = rtd(ang);

                                                    }
                                                    else
                                                    {
                                                        if (ang == Math.PI * 1.5)
                                                        {
                                                            azimuth = 180.0;

                                                        }
                                                        else
                                                        {
                                                            if (ang > Math.PI * 1.5 && ang < Math.PI * 2)
                                                            {
                                                                azimuth = rtd(ang) - 180.0;

                                                            }
                                                            else
                                                            {
                                                                if (ang == Math.PI * 2)
                                                                {
                                                                    azimuth = 90;

                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                ed.WriteMessage("X = {0:f3}\tY = {1:f3}\n", rtd(ang), azimuth);
                                sb.Append(string.Format("Azimuth = \t{0:f3}\n", azimuth));
                                sb.Append(string.Format("X = {0:f3}\tY = {1:f3}\n", pt.X, pt.Y));
                            }

                        }
                        acadApp.ShowAlertDialog(sb.ToString().TrimEnd(new char[] { '\n' }));
                    }
« Last Edit: April 06, 2011, 02:15:54 PM by fixo »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Distance and azimuth between vertices of a polyline in c#
« Reply #4 on: April 06, 2011, 01:41:22 PM »
Hi,

Here's a little sample (only lwpolylines in planes parallel to XY WCS plane)

Code: [Select]
        [CommandMethod("Test")]
        public static void Test()
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptEntityOptions peo = new PromptEntityOptions("\nSelect a polyline: ");
            peo.SetRejectMessage("\nNot a polyline");
            peo.AddAllowedClass(typeof(Polyline), true);
            PromptEntityResult per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Polyline pl = (Polyline)tr.GetObject(per.ObjectId, OpenMode.ForRead);
                for (int i = 0; i < pl.NumberOfVertices - 1; i++)
                {
                    LineSegment3d ls3d = pl.GetLineSegmentAt(i);
                    ed.WriteMessage("\nSegment {0}: from {1} to {2} Length: {3} Azimut: {4}",
                        i,
                        pl.GetPoint3dAt(i),
                        pl.GetPoint3dAt(1 + 1),
                        ls3d.Length,
                        GetAzimut(ls3d));
                }
                tr.Commit();
            }
        }

        private static double GetAzimut(LineSegment3d ls3d)
        {
            Vector3d dir = ls3d.Direction;
            return RadiansToDegrees(Vector3d.YAxis.GetAngleTo(dir, Vector3d.ZAxis));
        }

        private static double RadiansToDegrees(double ang)
        {
            return (ang / Math.PI) * 180.0;
        }
Speaking English as a French Frog

bieres

  • Guest
Re: Distance and azimuth between vertices of a polyline in c#
« Reply #5 on: April 06, 2011, 04:16:11 PM »
Hi Giles.

Your GetAzimut function has an error in the return angle.

Hola Gile.
Tu función GetAzimut, tiene un error, en la devolución del angulo.
Code: [Select]
private static double GetAzimut(LineSegment3d ls3d)
        {
            Vector3d dir = ls3d.Direction;
            Vector3d Yaxis = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Yaxis;
            return RadiansToDegrees(dir.GetAngleTo(Yaxis));
        }
« Last Edit: April 06, 2011, 06:59:16 PM by bieres »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Distance and azimuth between vertices of a polyline in c#
« Reply #6 on: April 07, 2011, 02:05:35 AM »
Hi,

I don't think it's wrong but it certainly do not return the result the way you expected.

If you want the angle from the segment direction to the Y axis (clockwise), use this :

Code: [Select]
        private static double GetAzimut(LineSegment3d ls3d)
        {
            return RadiansToDegrees(ls3d.Direction.GetAngleTo(Vector3d.YAxis, Vector3d.ZAxis));
        }

If this still do not reply your desire, post a picture showing what you want.
Speaking English as a French Frog