;;; --------------------------------------------------------------------- ;;; VXINTERP-bgol.lsp ;;; Command: VIZ ;;; ;;; PURPOSE ;;; When only the start and end elevations of a polyline are known, ;;; this routine calculates the elevation at every intermediate vertex ;;; by linear interpolation (proportional to distance along the ;;; polyline) and drops elevation text at each one. Useful for design ;;; gradelines, formation levels, and simplified breaklines where only ;;; the two endpoint elevations are defined. ;;; ;;; USAGE ;;; 1. Load this file (APPLOAD or drag-drop onto the drawing window). ;;; 2. Type VIZ at the command line and press Enter. ;;; 3. Select the polyline to interpolate. ;;; 4. Enter the known elevation at the START vertex. ;;; 5. Enter the known elevation at the END vertex. ;;; 6. Elevation text is created at every vertex (including the two ;;; endpoints for confirmation), interpolated proportionally to ;;; distance along the polyline, placed on layer "BGOL-VIZ". ;;; ;;; NOTES ;;; - This is an original, independently written implementation. ;;; It is INSPIRED by the general idea of linear-interpolation ;;; elevation utilities common in CAD/survey 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) (setq *bgol-viz-precision* 3) (defun BGOL:VIZ-EnsureLayer (lname / ) (if (not (tblsearch "LAYER" lname)) (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord") (cons 2 lname) '(70 . 0) '(62 . 1) ; red '(6 . "Continuous"))) ) ) (defun BGOL:VIZ-MakeText (pt elev lname / dxfdata) (setq dxfdata (list '(0 . "TEXT") '(100 . "AcDbEntity") (cons 8 lname) '(100 . "AcDbText") (cons 10 (list (car pt) (cadr pt) 0.0)) '(40 . 2.0) (cons 1 (rtos elev 2 *bgol-viz-precision*)) ) ) (entmake dxfdata) ) ;; Return list of 2D vertex points of an LWPOLYLINE, in order (defun BGOL:VIZ-Vertices (ent / edata pts) (setq edata (entget ent)) (setq pts '()) (foreach pair edata (if (= (car pair) 10) (setq pts (append pts (list (cdr pair)))) ) ) pts ) (defun C:VIZ ( / ent obj pts n i pt0 ptN elevStart elevEnd totalLen cumLen segLen frac elev pt prevpt) (BGOL:VIZ-EnsureLayer "BGOL-VIZ") (setq ent (car (entsel "\nSelect polyline to interpolate: "))) (if ent (progn (setq pts (BGOL:VIZ-Vertices ent)) (setq n (length pts)) (if (< n 2) (princ "\nSelected polyline needs at least 2 vertices.") (progn (setq elevStart (getreal "\nEnter known elevation at START vertex: ")) (setq elevEnd (getreal "\nEnter known elevation at END vertex: ")) (if (and elevStart elevEnd) (progn ;; total length along the polyline (2D, vertex to vertex) (setq totalLen 0.0) (setq prevpt (car pts)) (setq i 1) (while (< i n) (setq pt (nth i pts)) (setq totalLen (+ totalLen (distance prevpt pt))) (setq prevpt pt) (setq i (1+ i)) ) (if (< totalLen 1e-9) (setq totalLen 1.0)) ;; walk vertices again, accumulating distance for interpolation (setq cumLen 0.0) (setq prevpt (car pts)) (setq i 0) (while (< i n) (setq pt (nth i pts)) (if (> i 0) (setq cumLen (+ cumLen (distance prevpt pt))) ) (setq frac (/ cumLen totalLen)) (setq elev (+ elevStart (* frac (- elevEnd elevStart)))) (BGOL:VIZ-MakeText pt elev "BGOL-VIZ") (setq prevpt pt) (setq i (1+ i)) ) (princ (strcat "\nInterpolated elevation text created at " (itoa n) " vertices (BGOL-VIZ).")) ) (princ "\nBoth start and end elevations are required.") ) ) ) ) (princ "\nNo polyline selected.") ) (princ) ) (princ "\nVXINTERP-bgol.lsp loaded. Type VIZ to interpolate vertex elevations along a polyline.") (princ "\n -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --") (princ)