;;; --------------------------------------------------------------------- ;;; PLDIST-bgol.lsp ;;; Command: PDIST ;;; ;;; PURPOSE ;;; Measures the true distance ALONG a polyline between two picked ;;; points that both lie on it (rather than a straight-line distance ;;; between them), without trimming or duplicating the polyline. Also ;;; reports each individual segment length between intermediate ;;; vertices for cross-checking. ;;; ;;; USAGE ;;; 1. Load this file (APPLOAD or drag-drop onto the drawing window). ;;; 2. Type PDIST at the command line and press Enter. ;;; 3. Select the polyline (or 2D/3D polyline / lwpolyline) to ;;; measure along. ;;; 4. Pick (or snap near) a Start Point and an End Point on that ;;; polyline. ;;; 5. The routine reports the total path distance between the two ;;; points, labels each intermediate vertex-to-vertex segment ;;; length along the span, and places a total-distance label at ;;; the midpoint — all on layer "BGOL-PDIST". ;;; ;;; NOTES ;;; - Uses vlax-curve-getParamAtPoint / getDistAtParam, so it ;;; correctly follows curved (arc) segments as well as straight ;;; ones. ;;; - This is an original, independently written implementation. ;;; It is INSPIRED by the general idea of "distance along a path" ;;; measuring utilities common in survey/alignment drafting ;;; workflows, but the code, command name and file name here are ;;; new and are NOT copied from, nor identical to, any specific ;;; third-party product. ;;; ;;; --------------------------------------------------------------------- ;;; Developed and shared for the CAD community by: BGol Community ;;; Community website: https://bgol.in/ ;;; License: Open-source & free to use, modify, and share for all. ;;; Provided "as is", without warranty of any kind. ;;; --------------------------------------------------------------------- (vl-load-com) (defun BGOL:PDIST-EnsureLayer (lname / ) (if (not (tblsearch "LAYER" lname)) (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord") (cons 2 lname) '(70 . 0) '(62 . 2) ; yellow '(6 . "Continuous"))) ) ) (defun BGOL:PDIST-Text (pt txt ht lname / ) (entmake (list '(0 . "TEXT") '(100 . "AcDbEntity") (cons 8 lname) '(100 . "AcDbText") (cons 10 pt) (cons 40 ht) (cons 1 txt))) ) (defun C:PDIST ( / ent obj p1 p2 par1 par2 parLo parHi d1 d2 total i vparam vpt vdist prevDist prevPt segLen midp) (BGOL:PDIST-EnsureLayer "BGOL-PDIST") (setq ent (car (entsel "\nSelect polyline: "))) (if ent (progn (setq obj (vlax-ename->vla-object ent)) (setq p1 (getpoint "\nStart point (on polyline): ")) (setq p2 (if p1 (getpoint "\nEnd point (on polyline): "))) (if (and p1 p2) (progn (setq par1 (vlax-curve-getParamAtPoint obj (vlax-curve-getClosestPointTo obj p1))) (setq par2 (vlax-curve-getParamAtPoint obj (vlax-curve-getClosestPointTo obj p2))) (setq parLo (min par1 par2)) (setq parHi (max par1 par2)) (setq d1 (vlax-curve-getDistAtParam obj parLo)) (setq d2 (vlax-curve-getDistAtParam obj parHi)) (setq total (abs (- d2 d1))) (setq midp (vlax-curve-getPointAtDist obj (+ d1 (/ total 2.0)))) (BGOL:PDIST-Text midp (strcat "Total: " (rtos total 2 3)) 2.5 "BGOL-PDIST") ;; per-segment breakdown across integer vertex params in range (setq prevDist d1) (setq prevPt (vlax-curve-getPointAtDist obj d1)) (setq i (1+ (fix parLo))) (while (<= i (fix parHi)) (setq vparam (float i)) (setq vpt (vlax-curve-getPointAtParam obj vparam)) (setq vdist (vlax-curve-getDistAtParam obj vparam)) (setq segLen (abs (- vdist prevDist))) (BGOL:PDIST-Text (mapcar '(lambda (a b) (/ (+ a b) 2.0)) prevPt vpt) (rtos segLen 2 3) 2.0 "BGOL-PDIST") (setq prevDist vdist) (setq prevPt vpt) (setq i (1+ i)) ) (princ (strcat "\nPDIST: total distance along polyline = " (rtos total 2 3))) ) (princ "\nStart/end point not given.") ) ) (princ "\nNo polyline selected.") ) (princ) ) (princ "\nPLDIST-bgol.lsp loaded. Type PDIST to measure distance along a polyline between two points.") (princ "\n -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --") (princ)