How to find the coordinates of a line parallel to another on the same layer

How to find the coordinates of a line parallel to another on the same layer

mecoman6GF27
Advocate Advocate
902 Views
5 Replies
Message 1 of 6

How to find the coordinates of a line parallel to another on the same layer

mecoman6GF27
Advocate
Advocate

Hi everyone.

 

How could I do to identify the start and end coordinates of the parallel line closest to another and which are on the same layer?

 

Thanks a lot, bye.

0 Likes
Accepted solutions (1)
903 Views
5 Replies
Replies (5)
Message 2 of 6

hosneyalaa
Advisor
Advisor
0 Likes
Message 3 of 6

_gile
Consultant
Consultant

Hi,

 

You can try something like this:

        [CommandMethod("FINDPARALLEL")]
        public static void FindClosestParallelLineCmd()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var options = new PromptEntityOptions("\nSelect Line: ");
            options.SetRejectMessage("Must be a Line.");
            options.AddAllowedClass(typeof(Line), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK) 
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var source = (Line)tr.GetObject(result.ObjectId, OpenMode.ForRead);
                if (TryFindParallelLine(source, tr, out LineSegment3d line))
                {
                    ed.WriteMessage("\nStart point: {0:0.00} End point: {1:0.00}", line.StartPoint, line.EndPoint);
                }
                else
                {
                    ed.WriteMessage("\nNone parallel line");
                }
                tr.Commit();
            }
        }

        static bool TryFindParallelLine(Line source, Transaction tr, out LineSegment3d line)
        {
            string layer = source.Layer;
            var segment = new LineSegment3d(source.StartPoint, source.EndPoint);
            var direction = segment.Direction;
            var segments =
                ((BlockTableRecord)tr.GetObject(source.OwnerId, OpenMode.ForRead))
                .Cast<ObjectId>()
                .Where(id => id != source.ObjectId && id.ObjectClass.DxfName == "LINE")
                .Select(id => (Line)tr.GetObject(id, OpenMode.ForRead))
                .Where(l => l.Layer == layer)
                .Select(l => new LineSegment3d(l.StartPoint, l.EndPoint))
                .Where(s => s.Direction.IsParallelTo(direction));
            if (segments.Any())
            {
                line = segments.Aggregate((s1, s2) =>
                    (s1.GetDistanceTo(segment) < s2.GetDistanceTo(segment)) ? s1 : s2);
                return true;
            }
            else
            {
                line = null;
                return false;
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 4 of 6

mecoman6GF27
Advocate
Advocate

Hi, thank you so much for your help.

Your code works perfectly but I asked myself: how can I find the perpendicular distance between the two parallel lines?

 

img.jpg

 

I tried like this:

 

 

ed.WriteMessage (vbLf & "Perpendicular distance beetwen line1 and line2:" & line.StartPoint.DistanceTo (source.GetClosestPointTo (line.StartPoint, False)))

 

 

What I have written only works in three cases:

1. when the two lines are inclined at a certain angle;

2. when the two lines have the same length;

3. when I select the longest line.

If the two lines, horizontal or vertical, have a different length and I select the shorter line, I get the distance between points A and C and not the perpendicular distance between the two lines.

Where do you think I'm wrong?

Thanks a lot, bye.

0 Likes
Message 5 of 6

_gile
Consultant
Consultant
Accepted solution

As you certainly noticed, the code uses the LineSegment3d type which exposes a GetDistanceTo method. This method is used to find the closest parallel line.

        [CommandMethod("FINDPARALLEL")]
        public static void FindClosestParallelLineCmd()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;
            var options = new PromptEntityOptions("\nSelect Line: ");
            options.SetRejectMessage("Must be a Line.");
            options.AddAllowedClass(typeof(Line), true);
            var result = ed.GetEntity(options);
            if (result.Status != PromptStatus.OK) 
                return;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var source = (Line)tr.GetObject(result.ObjectId, OpenMode.ForRead);
                if (TryFindParallelLine(source, tr, out LineSegment3d line, out double distance))
                {
                    ed.WriteMessage(
                        "\nStart point: {0:0.00} End point: {1:0.00}\nDistance = {2:0.00}", 
                        line.StartPoint, 
                        line.EndPoint, 
                        distance);
                }
                else
                {
                    ed.WriteMessage("\nNone parallel line");
                }
                tr.Commit();
            }
        }

        static bool TryFindParallelLine(Line source, Transaction tr, out LineSegment3d line, out double distance)
        {
            string layer = source.Layer;
            var segment = new LineSegment3d(source.StartPoint, source.EndPoint);
            var direction = segment.Direction;
            var segments =
                ((BlockTableRecord)tr.GetObject(source.OwnerId, OpenMode.ForRead))
                .Cast<ObjectId>()
                .Where(id => id != source.ObjectId && id.ObjectClass.DxfName == "LINE")
                .Select(id => (Line)tr.GetObject(id, OpenMode.ForRead))
                .Where(l => l.Layer == layer)
                .Select(l => new LineSegment3d(l.StartPoint, l.EndPoint))
                .Where(s => s.Direction.IsParallelTo(direction));
            if (segments.Any())
            {
                line = segments.Aggregate((s1, s2) =>
                    (s1.GetDistanceTo(segment) < s2.GetDistanceTo(segment)) ? s1 : s2);
                distance = line.GetDistanceTo(segment);
                return true;
            }
            else
            {
                line = null;
                distance = -1.0;
                return false;
            }
        }


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 6 of 6

mecoman6GF27
Advocate
Advocate

Hi, thank you so much for your help.

Bye.

0 Likes