您的位置:网站首页 > CAD教程 > 常见问题

在AutoCAD中对集中特殊编辑功能的开发研究

时间:2010-11-12 13:10:36 来源:未知

AutoCAD作为强大而专业的工程绘图软件,提供了丰富的矢量图编辑工具,但也有一些常用的特殊编辑功能没有提供,给交互式绘图工作中的图形编辑带来了不便。例如, 在绘制地理图时, 经常遇到绘制铁路线;在手动矢量化过程中,为精确调整矢量图与底图的符合程度, 需要增加或减少多义线节点。这些功能AutoCAD缺省时无法实现,如果通过编程让计算机自动完成上述功能,则既可提高工作效率又可减轻工程设计人员的劳动强度。

  AutoCAD软件提供了许多开放式接口,允许用户通过这些接口对AutoCAD进行二次开发,为AutoCAD增加新功能,以满足用户的工作需要。LISP语言程序就是常用的一种,在AutoCAD R14中,将编写的LISP程序(函数)加入到ACADr14.LSP 文件中,这些函数就如同AutoCAD的基本命令一样,非常方便。下面开发的几个LISP函数程序分别实现了绘制铁路线型、多义线节点的增加、删除操作等特殊编辑功能。

  绘制铁路线型

  1.程序设计思路

  在AutoCAD的线型库文件ACAD.LIN、ACADISO.LIN分别新增实线段与空白段之比为1∶1、名为“Railway” 的线型,描述格式如下:

  在ACAD.LIN中增加:

  *Railway,Railway — —

  A,1,-1

  在ACADISO.LIN中增加:

  *Railway,Railway — —

  A,15,-15

  通过对选定多义线设置线宽(铁路线宽),原点拷贝,将由拷贝生成的多义线设置为新建的“铁路”图层,颜色设为“白色”,线型设为“Railway”,线宽为原线宽的0.7倍,这样原多义线与叠加在其上的宽度稍窄的白色虚线就构成了形象逼真的铁路线。

  2.程序代码

  (defun c:tlx()

  (setvar “cmdecho” 0)

  (setq ss (ssget ‘((0 .“LWPOLYLINE”))))

  (if (equal ss NIL)

  (exit) ; 没有选择对象或已取消

  )

  (setq tlkd (getstring“请输入铁路线宽度:”))

  (command “pedit” ss “width” tlkd “”)

  (command “copy” ss “” “0,0” “0,0” “”)

  (command “layer” “m” “铁路” “L” “Railway” “” “”)

  (command “layer” “s” “铁路” “c” “255” “” “”)

  (setq sset (ssget “L”))

  (command “pedit” sset “width” (setq tlkd1 (* (atof tlkd) 0.7)) “L” “ON” “”)

  (setq ename1 (ssname sset 0)

  ent1 (entget ename1))

  (setq ent11 (nth 5 ent1))

  (setq ent11 (subst (cons 8 “铁路”) ent11 ent1))

  (entmod ent11)

  (setq ent12 (nth 6 ent11))

  (setq ent12 (subst (cons 6 “Railway”) ent12 ent11))

  (entmod ent12)

  )

  增加多义线节点

  1. 程序设计思路

  选定多义线,通过设置“最近点”捕捉方式精确定位所增加节点的位置。提取多义线的定义数据表中的节点坐标,通过检测添加点到相邻两节点距离之和是否等于两节点间距离的方法,判断添加节点所在的位置。把添加点的坐标插入数据表中与之相邻的两节点坐标之间,并对多义线的定义数据表进行更新,以达到增加节点的目的。

  2. 程序代码

  (defun c:add_V()

  ; add_Vertex.lsp

  ; 要求用户选定多义线

  (princ “ Select LWPolylines: ”)

  (setq ss (ssget ‘((0 . “LWPOLYLINE”))))

  (if (equal ss NIL)

  (exit)) ; 没有选择对象或已取消

  ; 获得单个多义线

  (setq ename (ssname ss 0)

  ent (entget ename)

  listlength (length ent)

  elementcounter 1)

  (setq e2 (entsel“请增加一个节点:”))

  (setq ent11 (nth 1 e2))

  (setq ent11 (osnap ent11 “nea”))

  ;最近点精确捕捉

  (setq e3 (cons 10 ent11))

  (setq el10 (list (car ent)))

  (setq el20 (cdr (assoc 10 ent)))

  (setq element2 el20)

  (setq k 0)

  ; 从多义线清单中获得每个元素

  (while (< elementcounter listlength)

  ; 从表中获得一个元素

  (setq element (nth elementcounter ent)

  kind (car element))

  (if (equal kind 10)

  ; 该元素所含的坐标

  (progn

  ; 获取坐标 (OCS系统)

  (setq OCSpoint (list (nth 1 element); x坐标

  (nth 2 element))) ; y坐标

  (setq element2 (trans OCSpoint ename 1)); 将OCS系统转为UCS系统

  (setq element1 (cons 10 element2))

  (setq dist (distance element2 el20))

  (setq dist1 (distance ent11 element2))

  (setq dist2 (distance ent11 el20))

  (setq dist (rtos dist 2 4))

  (setq dist1 (rtos dist1 2 4))

  (setq dist2 (rtos dist2 2 4))

  (if (= (atof dist) (+ (atof dist1) (atof dist2)));判断节点位置并将其坐标加入表中

  (progn

  (setq ent11 (trans ent11 1 ename))

  ;将UCS系统转为OCS系统

  (setq e3 (cons 10 ent11))

#p#分页标题#e#

  (setq el10 (cons e3 el10))

  (setq k 1)

  )

  )

  )

  )

  (setq el1 (cons element el10))

  (setq kind “”)

  (setq elementcounter (1+ elementcounter))

  (setq el10 el1)

  (setq el20 element2)

  )

  (if (= k 0) (print “添加点没选中,重试!”))

  (setq ent (reverse el1))

  (entmod ent);表更新

  (setq ss NIL)

  (princ “ Ready.”)

  (princ)

  )

  多义线节点的删除

  1. 程序设计思路

  选定多义线,通过设置“端点”、“交点”捕捉方式定位删除节点的位置。提取多义线的定义数据表中的节点坐标,通过检查所删节点在定义数据表中的位置,把数据表中的对应节点坐标数据删除,并对多义线的定义数据表进行更新,以达到删除节点的目的。

  2. 程序代码;

  remove_vertex.lsp

  (defun c:rem_v(); 要求用户选定多义线

  (princ “ Select LWPolylines: ”)

  (setq ss (ssget ‘((0 . “LWPOLYLINE”))))

  (if (equal ss NIL)

  (exit) ; 没有选择对象或已取消); 获得单个多义线

  (setq ename (ssname ss 0)

  ent (entget ename)

  listlength (length ent)

  elementcounter 1)

  (setq e2 (entsel“请选择一个节点:”))

  (setq ent11 (nth 1 e2))

  (setq ent11 (osnap ent11 “int,end”))

  (setq e3 (cons 10 ent11))(setq el10 (list (car ent))); 从表中获得每个元素

  (while (< elementcounter listlength); 从表中获得一个元素

  (setq element (nth elementcounter ent)

  kind (car element))

  (if (equal kind 10); 该元素所含的坐标

  (progn; 获取坐标 (以OCS系统)

  (setq OCSpoint (list (nth 1 element); x坐标

  (nth 2 element))) ; y坐标

  (setq element1 (trans OCSpoint ename 1))

  ; 将OCS系统转为UCS系统

  (setq element1 (cons 10 element1))

  )

  )

  (if (equal element1 e3)

  (setq el1 el10)

  (setq el1 (cons element el10))

  )

  (setq element1 “”)

  (setq elementcounter (1+ elementcounter))

  (setq el10 el1)

  )

  (setq ent (reverse el1))

  (entmod ent)

  (setq ss NIL)

  (princ “ Ready.”)

  (princ)

  )

  应当指出的是上述多义线节点的增加、删除操作适合于任何用户坐标系统的图形文件。在程序设计中,还涉及到坐标系统转换,即OCS系统(对象坐标系统)与UCS(用户坐标系统)之间的转换,原因是多义线定义数据表中的坐标为对象坐标,屏幕图元的显示坐标为用户坐标,在非WCS(世界坐标系)坐标系中,屏幕上同一点对象坐标与显示坐标是不同的,因此,在两者坐标数据进行比较时必须使用同一种坐标系。