Community
AutoCAD Forum
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

measure lengths of 3D polyline using lisp & draw Centerline

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
k_l_raghava
2191 Views, 8 Replies

measure lengths of 3D polyline using lisp & draw Centerline

Hi,

 

Thanks in advance,

 

3D Polyline length:

I want to measure 3D polyline length from a total station survey data and lines drawn connecting points. when i am using the other lisps it is not calculating the 3D lengths. around 800 kms of lines are in my drawing.

 

Note. attached is a part drawing.

 

Center line:

Also center line to be draw in new layer in between those lines.

 

Please help me.

8 REPLIES 8
Message 2 of 9
CodeDing
in reply to: k_l_raghava

@k_l_raghava ,

 

There is nothing attached. Can you try again?

~DD
Senior CAD Tech & AI Specialist
Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 3 of 9
k_l_raghava
in reply to: CodeDing

sorry,

 

Please find the attached one now.

Message 4 of 9
CodeDing
in reply to: k_l_raghava

@k_l_raghava ,

 

Maybe I do not fully understand what you are requesting. Is there something wrong with using the "Length" property of the line?

 

Are you trying to get the TOTAL of all selected 3D Polylines?

 

image.png

 

Best,

~DD

~DD
Senior CAD Tech & AI Specialist
Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 5 of 9
k_l_raghava
in reply to: CodeDing

hi,

 

Actually there are many polyline approximating to 900 kms, selecting individual lines will not be possible, hence needed a lisp. 

using Tlen.lsp from internet and result showing zero, may be due to 3D polyline.

 

Also want to insert centerline, Annotate-> Centerlines is not detecting those as lines.

Message 6 of 9
CodeDing
in reply to: k_l_raghava

@k_l_raghava ,

 

Try this routine and let me know if it is what you are looking for:

(defun c:TLEN ( / tlen str eList)
  (setq tlen
    (apply '+
      (mapcar
        '(lambda (e) (getpropertyvalue e "Length"))
        (foreach s (ssnamex (ssget '((0 . "*POLYLINE,LINE,ARC"))))
          (if (>= (car s) 0) (setq eList (cons (cadr s) eList)))
          eList
        );foreach
      );mapcar
    );apply
  );setq
  (setq str (strcat "\nTotal Length = " (rtos tlen)))
  (prompt str)
  (alert str)
  (princ)
);defun

 


Also want to insert centerline, Annotate-> Centerlines is not detecting those as lines.


I will not be able to help with this request ^^^ Since I cannot think of an effective method to get the centerline between two 3D polylines..

---EDIT---

Updated code to include ARC

 

Best,

~DD

~DD
Senior CAD Tech & AI Specialist
Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
Message 7 of 9
k_l_raghava
in reply to: CodeDing

Thanks

Message 8 of 9
Kent1Cooper
in reply to: k_l_raghava


@k_l_raghava wrote:

... there are many polyline approximating to 900 kms, selecting individual lines will not be possible, hence needed a lisp. 

using Tlen.lsp from internet and result showing zero, may be due to 3D polyline.

....


The Addline.lsp routine >here< works with 3DPolylines [and also Arcs, not covered by Message 6].  I'm sure there are many other such routines out there, some of which would also work with Circles, Ellipses, and Splines.

 

[As for the centerline, that would not be difficult if both had the same number of vertices that were consistently opposite each other across the roadway width, and their ends aligned, but neither is the case in your example.  You can always use the M2P or MTP object snap between those points that are across from each other, as tedious as that would be.  I don't know of a way to automate it.]

Kent Cooper, AIA
Message 9 of 9
Kent1Cooper
in reply to: Kent1Cooper


@Kent1Cooper wrote:
.....

[As for the centerline, ....  I don't know of a way to automate it.]


Well, I thought of something, though it may not be quite what you need.  This traces along the shorter  of the two 3DPolylines selected, and at each vertex, finds the closest point on the other one, calculates the point halfway between them, and it draws a 3DPolyline through the halfway-between locations.  It doesn't account for places where there isn't a vertex on the shorter one approximately "lined up with" or "across from" one on the longer one, but in the sample drawing, there's only one such location, and in a pretty straight stretch, so the effect on the result is minimal.  At the left end, it does this because of the little perpendicular leg:
3DCL1.PNG

And since it finds the closest point  on the across-the-road 3DPolyline, not necessarily the closest vertex across the road [since in some places there isn't one roughly across the road], this kind of thing happens:

3DCL2.PNG

where the shorter one that it's stepping along is the lower red one, the dotted line is reaching across to the closest point on the longer one above, and the vertex on the new 3DPolyline is the midpoint between those locations, not  the midpoint between roughly-across-from-each-other vertices.  I thought of having it find the nearest vertex, but that could cause trouble where there isn't  one close to across-the-road.

 

But if that's close enough for you, it does  follow the Z-coordinate variability in the 3D-ness of the source Polylines.

(vl-load-com)
(defun C:3DCL (/ ss 3DplA 3DplB lenA lenB 3Dpl1 3Dpl2 n vert1 pt2)
  (prompt "\nTo draw a Center-Line between two 3D Polylines,")
  (if
    (and
      (setq ss (ssget '((0 . "POLYLINE"))))
      (= (sslength ss) 2)
      (= (cdr (assoc 100 (reverse (entget (ssname ss 0))))) "AcDb3dPolyline")
      (= (cdr (assoc 100 (reverse (entget (ssname ss 1))))) "AcDb3dPolyline")
    ); and
    (progn ; then
      (setq
        3DplA (ssname ss 0)
        3DplB (ssname ss 1)
        lenA (vlax-curve-getDistAtParam 3DplA (vlax-curve-getEndParam 3DplA))
        lenB (vlax-curve-getDistAtParam 3DplB (vlax-curve-getEndParam 3DplB))
        3Dpl1 (if (< lenA lenB) 3DplA 3DplB); shorter one
        3Dpl2 (ssname (ssdel 3Dpl1 ss) 0); longer one
        n -1
      ); setq
      (command "_.3dpoly")
      (repeat (+ (fix (vlax-curve-getEndParam 3Dpl1)) (if (vlax-curve-isClosed 3Dpl1) 0 1))
        (setq
          vert1 (vlax-curve-getPointAtParam 3Dpl1 (setq n (1+ n))); vertex on shorter
          pt2 (vlax-curve-getClosestPointTo 3Dpl2 vert1); closest point to it on longer
        ); setq
        (command "_none" (mapcar '/ (mapcar '+ vert1 pt2) '(2 2 2))); midway between
      ); repeat
      (command (if (vlax-curve-isClosed 3Dpl1) "_close" ""))
    ); progn
    (prompt "\nYou must select two and only two 3DPolylines."); else
  ); if
  (princ)
); defun
(prompt "\nType 3DCL to draw a Center-Line between two 3DPolylines.")
(princ)

If you could get them to always have the same number of vertices, and to both cover about the same extent without one stretching well beyond the end(s) of the other, a variant on SplineAverage.lsp, >here<, could be made for 3DPolylines.

Kent Cooper, AIA

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

Post to forums  

Forma Design Contest


AutoCAD Beta