批量提取直线和多段线顶点坐标并输出到DAT文件
本帖最后由 zyx1029 于 2025-9-11 08:45 编辑自己写了一部分,效果不太好。又让AI给加工了一下
;; 批量提取直线和多段线顶点坐标并输出到DAT文件,同时标注点号和多段线(或直线)编号
(defun C:TQZB (/ *error* ss filename file i ent_tqzb objType vertexList_tqzb allVertices pointCounter j vertexData textHeight lineCounter polylineCounter oldOSMODE)
;; 错误处理函数
(defun *error* (msg)
(if (and msg (not (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")))
(princ (strcat "\n错误: " msg))
)
(if file (close file))
(setvar "OSMODE" oldOSMODE) ; 恢复捕捉模式
(princ)
)
(vl-load-com)
(setq oldOSMODE (getvar "OSMODE")) ; 保存当前捕捉模式
;; 获取文本高度
(setq textHeight (getdist "\n请输入点号文本高度<1>: "))
(if (not textHeight)
(setq textHeight 1.0) ; 默认文本高度
)
;; 提示用户选择直线和多段线
(setq ss (ssget '((0 . "LINE,LWPOLYLINE,POLYLINE"))))
(if (not ss)
(progn
(princ "\n未选择任何对象。")
(exit)
)
)
;; 获取输出文件名
(setq filename (getfiled "指定输出DAT文件" "" "dat" 1))
(if (not filename)
(progn
(princ "\n未指定输出文件。")
(exit)
)
)
;; 打开文件用于写入
(setq file (open filename "w"))
(if (not file)
(progn
(princ "\n无法创建文件。")
(exit)
)
)
(setq allVertices nil)
(setq pointCounter 1) ; 初始化全局点号计数器
(setq lineCounter 1) ; 初始化直线编号计数器
(setq polylineCounter 1) ; 初始化多段线编号计数器
;; 遍历选择集中的每个图元
(setq i 0)
(while (< i (sslength ss))
(setq ent_tqzb (ssname ss i))
(setq objType (cdr (assoc 0 (entget ent_tqzb))))
;; 根据图元类型获取顶点列表
(cond
;; 处理直线
((= objType "LINE")
(setq vertexList_tqzb (list
(cdr (assoc 10 (entget ent_tqzb))) ; 起点
(cdr (assoc 11 (entget ent_tqzb))) ; 终点
))
)
;; 处理轻量多段线和多段线
((or (= objType "LWPOLYLINE") (= objType "POLYLINE"))
(setq vertexList_tqzb (get-polyline-vertices ent_tqzb))
)
)
;; 将当前图元的顶点信息添加到总列表
(setq allVertices (cons (list objType vertexList_tqzb) allVertices))
(setq i (1+ i))
)
;; 反转列表以保持选择顺序
(setq allVertices (reverse allVertices))
;; 关闭捕捉模式
(setvar "OSMODE" 0)
;; 写入顶点数据到文件并标注点号
(setq i 0)
(foreach entity allVertices
(setq objType (car entity))
(setq vertexList_tqzb (cadr entity))
(setq vertexCount (length vertexList_tqzb))
;; 根据对象类型确定标注类型
(cond
((= objType "LINE")
;; 处理直线
(setq centerPoint (get-line-center_tqzb vertexList_tqzb))
(setq angle (get-line-angle vertexList_tqzb))
(setq offsetPoint (get-offset-point_tqzb centerPoint angle (* textHeight 1.5)))
;; 在DAT文件中写入直线编号
(write-line (strcat "直线" (itoa lineCounter)) file)
;; 在偏移位置添加编号文本标注,方向与线平行
(create-text_tqzb-at-point_tqzb offsetPoint (strcat "直线" (itoa lineCounter)) textHeight angle)
(setq lineCounter (1+ lineCounter))
)
((or (= objType "LWPOLYLINE") (= objType "POLYLINE"))
;; 处理多段线
(if (= vertexCount 2)
(progn
;; 两个顶点的多段线,处理方式类似直线
(setq centerPoint (get-line-center_tqzb vertexList_tqzb))
(setq angle (get-line-angle vertexList_tqzb))
(setq offsetPoint (get-offset-point_tqzb centerPoint angle (* textHeight 1.5)))
;; 在DAT文件中写入多段线编号
(write-line (strcat "多段线" (itoa polylineCounter)) file)
;; 在偏移位置添加编号文本标注,方向与线平行
(create-text_tqzb-at-point_tqzb offsetPoint (strcat "多段线" (itoa polylineCounter)) textHeight angle)
)
(progn
;; 三个顶点以上的多段线
(write-line (strcat "多段线" (itoa polylineCounter)) file)
;; 在多段线中心位置添加编号文本标注
(setq centerPoint (get-polyline-center_tqzb vertexList_tqzb))
(create-text_tqzb-at-point_tqzb centerPoint (strcat "多段线" (itoa polylineCounter)) textHeight 0)
)
)
(setq polylineCounter (1+ polylineCounter))
)
)
(setq localPointCounter 1) ; 每条多段线独立的点号计数器,从1开始
(setq j 0)
(foreach vertex vertexList_tqzb
;; 创建点号文本(格式: J1, J2, J3, ...)
(setq pointText (strcat "J" (itoa localPointCounter)))
;; 在顶点位置创建文本标注
(create-text_tqzb-at-point_tqzb vertex pointText textHeight 0)
;; 格式化坐标数据(用于文件输出)
(setq vertexData (strcat
pointText ; 地块点号
",,"
(rtos (car vertex) 2 3) ; X坐标
","
(rtos (cadr vertex) 2 3) ; Y坐标
",0.00" ; 固定高程值
))
;; 写入到文件
(write-line vertexData file)
(setq j (1+ j))
(setq localPointCounter (1+ localPointCounter)) ; 递增局部点号计数器
(setq pointCounter (1+ pointCounter)) ; 递增全局点号计数器
)
;; 在多段线/直线数据之间添加空行(除非是最后一个)
(if (< i (1- (length allVertices)))
(write-line "" file)
)
(setq i (1+ i))
)
;; 关闭文件
(close file)
(setq file nil)
;; 恢复捕捉模式
(setvar "OSMODE" oldOSMODE)
(princ (strcat "\n成功提取并保存了 " (itoa (1- pointCounter)) " 个顶点到 " filename))
(princ)
)
;; 获取多段线的所有顶点坐标
(defun get-polyline-vertices (ent_tqzb / entData vertices vertex)
(setq entData (entget ent_tqzb))
(setq vertices '())
;; 遍历图元数据表,提取所有顶点(组码10)
(foreach item entData
(if (= (car item) 10)
(progn
(setq vertex (cdr item))
;; 确保顶点有Z坐标(如果没有,设为0.0)
(if (< (length vertex) 3)
(setq vertex (list (car vertex) (cadr vertex) 0.0))
)
(setq vertices (cons vertex vertices))
)
)
)
;; 返回反转的顶点列表(保持原始顺序)
(reverse vertices)
)
;; 计算多段线的大致中心点
(defun get-polyline-center_tqzb (vertexList_tqzb / minX maxX minY maxY)
(setq minX (apply 'min (mapcar 'car vertexList_tqzb))
maxX (apply 'max (mapcar 'car vertexList_tqzb))
minY (apply 'min (mapcar 'cadr vertexList_tqzb))
maxY (apply 'max (mapcar 'cadr vertexList_tqzb)))
(list (/ (+ minX maxX) 2) (/ (+ minY maxY) 2) 0.0)
)
;; 计算直线的中心点
(defun get-line-center_tqzb (vertexList_tqzb)
(list
(/ (+ (car (nth 0 vertexList_tqzb)) (car (nth 1 vertexList_tqzb))) 2.0)
(/ (+ (cadr (nth 0 vertexList_tqzb)) (cadr (nth 1 vertexList_tqzb))) 2.0)
0.0
)
)
;; 计算直线的角度(弧度)
(defun get-line-angle (vertexList_tqzb)
(setq p1 (nth 0 vertexList_tqzb)
p2 (nth 1 vertexList_tqzb))
(atan (- (cadr p2) (cadr p1)) (- (car p2) (car p1)))
)
;; 计算偏移点(垂直于直线方向)
(defun get-offset-point_tqzb (center_tqzb angle distance)
(list
(+ (car center_tqzb) (* distance (cos (+ angle (/ pi 2)))))
(+ (cadr center_tqzb) (* distance (sin (+ angle (/ pi 2)))))
0.0
)
)
;; 在指定点创建文本
(defun create-text_tqzb-at-point_tqzb (point_tqzb text_tqzb height_tqzb angle / oldOSMODE)
(setq oldOSMODE (getvar "OSMODE")) ; 保存当前捕捉模式
(setvar "OSMODE" 0) ; 关闭捕捉模式
(command "_.text"
"_J" "_MC" ; 中间中心对齐
point_tqzb ; 插入点
height_tqzb ; 文字高度
(* (/ angle pi) 180) ; 旋转角度(转换为度)
text_tqzb ; 文本内容
)
(setvar "OSMODE" oldOSMODE) ; 恢复捕捉模式
)
;; 加载提示
(princ "\n输入命令 TQZB 开始提取顶点坐标并标注点号和多段线(或直线)编号。")
(princ)
luoyiandy 发表于 2025-9-10 11:30
可以,不错,挺好用,要是能直接生成表格在CAD上就更好了
安排一个,两种模式可选!
bai2000 发表于 2025-9-12 12:08
指定基点,以基点绘制其余点到基点的相对x/y的相对坐标值
我好像没明白 bai2000 发表于 2025-9-12 10:44
不错,能指定基点,绘制相对坐标么?
提取指定点的坐标到文件或表格? 可以,不错,挺好用,要是能直接生成表格在CAD上就更好了 非常好用 感谢分享 感谢分享。
感谢分享。
多谢分享!!!!!! 不错 加油 支持你 zyx1029 发表于 2025-9-11 08:43
安排一个,两种模式可选!
不错,能指定基点,绘制相对坐标么?
页:
[1]
2