找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2413|回复: 10

[LISP程序]:添加和移除多段线顶点的小程序

[复制链接]
发表于 2006-4-6 19:38:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
XD工具箱中有添加和移除多段线上的顶点的命令.给多段线的编辑带来了很大的方便.但自从我升级到2006就不能用了.不知为何?
没办法,只好自己动手啦.趁着学习VLISP的热情,就写了个模拟这种功能的程序,所不同之处是我根据工作中的实际需要,使它可以反复地在一条线上加入或删除顶点.因为是刚开始真正学习VLISP编程,所以一定还有许多不合理,不足之处,还请各位前辈学长指正.不胜感激

  1. ;;;-----------------------------------------------------------------------
  2. ;;;顾名思义,本LISP文件是对ACAD函数的一些扩充。其中包含多个自行编写的函数
  3. ;;;(命令),用以解决工作中一些小问题,籍以提高工作效率。
  4. ;;;这些工具,都是作者们在工作一点点地积累而成。也许从程序设计的各项评判指标
  5. ;;;来看,并不是很严谨、优化,肯定有许多的不足之处。但若仅从解决实际问题的角
  6. ;;;度来讲,能够让工作的繁琐得到哪怕是一丁点的减轻,也算是努力没有白费。
  7. ;;;当然,精益求精、尽善尽美是我们不懈追求的目标,这是永远都不会改变的!
  8. ;;;因此,对于个中的不足之处,还请各位前辈不吝指出,小弟先行在此致谢!
  9. ;;;最后,祝您工作愉快!
  10. ;;;我的Email:  [email]IamYourHe@163.com[/email]   我的手机: 13568953509     何俊
  11. ;;;-----------------------------------------------------------------------
  12. (SETQ *acad-object* nil)                ; Initialize global variable
  13. (DEFUN acad-object ()
  14.   (COND        (*acad-object*)                        ; Return the cached object
  15.         (T
  16.          (SETQ *acad-object* (VLAX-GET-ACAD-OBJECT))
  17.         )
  18.   ) ;_ 结束cond

  19. ) ;_ 结束defun

  20. (SETQ *active-document* nil)                ; Initialize global variable
  21. (DEFUN active-document ()
  22.   (COND        (*active-document*)                ; Return the cached object
  23.         (T
  24.          (SETQ *active-document* (VLA-GET-ACTIVEDOCUMENT (acad-object)))
  25.         )
  26.   ) ;_ 结束cond

  27. ) ;_ 结束defun

  28. (SETQ *model-space* nil)                ; Initialize global variable
  29. (DEFUN model-space ()
  30.   (COND        (*model-space*)                        ; Return the cached object
  31.         (T
  32.          (SETQ *model-space* (VLA-GET-MODELSPACE (active-document)))
  33.         )
  34.   ) ;_ 结束cond


  35. ) ;_ 结束defun
  36. (VL-LOAD-COM)
  37. ;;;以上代码取自AutoCad2000帮助文件
  38. ;;;--------------------------------------------------------

  39. ;;;--------------------------------------------------------
  40. ;;;函数: c:FunHelp                       
  41. ;;;--------------------------------------------------------
  42. ;;;编制日期:2006.3.31
  43. ;;;编制者  :何俊
  44. ;;;函数说明:显示本文件内函数(命令)的相关信息
  45. ;;;--------------------------------------------------------
  46. (DEFUN c:FunHelp ()
  47.   (PRINT)
  48.   (TEXTSCR)
  49.   (PRINC "\n AddFun自定义命令一览")
  50.   (PRINC "\n----------------------------------")
  51.   (PRINC "\n  命令             功能")
  52.   (PRINC "\n----------------------------------")
  53.   (PRINC "\n Bfill  ........区域植被填充")
  54.   (PRINC "\n AddVertex......在多段线上添加顶点")
  55.   (PRINC "\n RemoveVertex...移除多段线上的顶点")
  56.   (PRINC "\n CC.............多重复制")
  57.   (PRINC "\n Swp............选择用户指定多边形内的实体")
  58.   (PRINC "\n                (注意多边形要在当前视口内)")
  59.   (PRINC "\n Cwp............选择用户指定多边形内以及与多边形相交的实体")
  60.   (PRINC "\n                (注意多边形要在当前视口内)")
  61.   (PRINC "\n ES.............选择用户指定多边形外的实体")
  62.   (PRINC "\n                (注意多边形要在当前视口内)")
  63.   (PRINC "\n Cs.............用户指定多边形外且不与多边形相交实体")
  64.   (PRINC "\n                (注意多边形要在当前视口内)")
  65.   (PRINC "\n----------------------------------")
  66.   (PRINC "\n 谢谢您的使用!愿您工作愉快!")
  67.   (PRINC)
  68. ) ;_ 结束defun

  69. ;;;-------------------------------------------
  70. ;;;函数名:RemoveVertex       
  71. ;;;-------------------------------------------
  72. ;;;来源:     作者:何俊   
  73. ;;;编制时间:2006.3.31
  74. ;;;功能  :删除多段线顶点
  75. ;;;语法  :(RemoveVertex)
  76. ;;;参数  :
  77. ;;;返回值:成功....T    失败...nil
  78. ;;;备注  :
  79. ;;;-------------------------------------------
  80. (DEFUN c:RemoveVertex (/         eName           obj             objNew
  81.                        plObj         pp           n             Plist
  82.                        neElev         nuVertex  arry1     #Plist
  83.                        nuLen         nuID           #temp1    vaPlist
  84.                        entClose         entLinet  entLines  entLinew
  85.                        entThick         enttruec  entconwidth
  86.                       )
  87.   (PRINC "\n RevmoveVertex......删除多段线的顶点(2006.3)")
  88.   (SETQ ss1 (ENTSEL "\n请选择一条多段线:"))
  89.   (SETQ eName (CAR ss1))
  90.   (SETQ p (CAR (CDR (ENTSEL "\n请选择要移除的顶点:"))))
  91.   (SETQ obj (VLAX-ENAME->VLA-OBJECT eName))
  92.   (WHILE p
  93.     (IF        objNew
  94.       (SETQ obj objNew)
  95.     ) ;_ 结束if
  96.     (IF
  97.       (WCMATCH
  98.         (VLA-GET-OBJECTNAME obj)
  99.         "LWPOLYLINE,AcDbPolyline"
  100.       ) ;_ 结束wcmatch
  101.        (PROGN
  102.          (SETQ pp (VLAX-CURVE-GETCLOSESTPOINTTO obj (TRANS p 1 0)))
  103.          ;;通过(VLAX-CURVE-GETPARAMATPOINT obj pp)取得的参数的值为小数
  104.          ;;如0.8579说明用户所点取的P位置在0到1号点之间,且0-P/0-1为0.8579,点位接近1点
  105.          ;;由此,可能确定用户希望移除的是哪一个顶点。
  106.          (SETQ n (ATOI (RTOS (VLAX-CURVE-GETPARAMATPOINT obj pp) 2 0)))
  107.          ;;提出多段线的顶点坐标
  108.          (SETQ Plist
  109.                 (VLAX-SAFEARRAY->LIST
  110.                   (VLAX-VARIANT-VALUE
  111.                     (VLA-GET-COORDINATES obj)
  112.                   ) ;_ 结束vlax-variant-value
  113.                 ) ;_ 结束vlax-safearray->list
  114.          ) ;_ 结束setq
  115.          ;;求算数组上下标,先求出Vertex的数目
  116.          (SETQ nuVertex (+ (FIX (VLAX-CURVE-GETENDPARAM obj)) 1))
  117.          ;;若多段线为闭合的,通过上行语句求出的Vertex数目将会多一个
  118.          ;;在下面的判断语句中减去
  119.          (IF (= (VLA-GET-CLOSED obj) :VLAX-TRUE)
  120.            (SETQ nuVertex (- nuVertex 1))
  121.          ) ;_ 结束if
  122.          ;;计算数组上下标
  123.          (SETQ array1 (CONS 0 (- (* (- nuVertex 1) 2) 1)))
  124.          (SETQ #plist (VLAX-MAKE-SAFEARRAY VLAX-VBDOUBLE array1))
  125.          ;;计算顶点表内元素个数
  126.          (SETQ nuLen (LENGTH Plist))
  127.          ;;根据n值,将点P的坐标插入到Plist中,先将Plist转为XYZ样式
  128.          (SETQ nuID 0)
  129.          (SETQ #templ nil)
  130.          ;;若点取的为第一个点
  131. ;;;         (if (= n 0)
  132. ;;;           (setq nuID 2
  133. ;;;                 nuLen (- nuLen 2)
  134. ;;;           ))
  135. ;;;         ;;若点取的为最后一个点
  136. ;;;         (if (= n  nuVertex)
  137. ;;;           (setq nuLen (- nuLen 2))
  138. ;;;           )

  139.          (REPEAT nuLen
  140.            (IF (OR (= nuID (* n 2)) (= nuID (+ (* n 2) 1)))
  141.              (PROGN
  142.              )
  143.              (SETQ #templ (APPEND #templ (LIST (NTH nuID Plist))))

  144.            ) ;_ 结束if

  145.            (SETQ nuID (+ 1 nuID))
  146.          ) ;_ 结束repeat
  147.          (VLAX-SAFEARRAY-FILL #Plist #temPl)
  148.          ;;由数组生成变体
  149.          (SETQ vaPlist (VLAX-MAKE-VARIANT #Plist))
  150.          ;;删除旧线,换上新线.要匹配的项目
  151.          ;;Closed......闭合    Layer.........图层
  152.          ;;Linetype....线型    LinetypeScale.线型缩放比例
  153.          ;;Lineweight..线宽    PlotStyleName.打印样式名
  154.          ;;Thickness...厚度    TrueColor.....颜色
  155.          (SETQ entClose           (VLA-GET-CLOSED obj)
  156.                entLayer           (VLA-GET-LAYER obj)
  157.                entLinet           (VLA-GET-LINETYPE obj)
  158.                entLines           (VLA-GET-LINETYPESCALE obj)
  159.                entLinew           (VLA-GET-LINEWEIGHT obj)
  160.                entThick           (VLA-GET-THICKNESS obj)
  161.                entTruec           (VLA-GET-TRUECOLOR obj)
  162.                entEleva           (VLA-GET-ELEVATION obj)
  163.                entConwidth (VLA-GET-CONSTANTWIDTH obj) ;_全局宽度
  164.                entLTGen           (VLA-GET-LINETYPEGENERATION obj) ;_线型生成

  165.          ) ;_ 结束setq
  166.          ;;删除原来的线
  167.          (SETQ eName (VLAX-VLA-OBJECT->ENAME obj))
  168.          (ENTDEL eName)
  169.          (SETQ objNew (VLA-ADDLIGHTWEIGHTPOLYLINE (model-space) vaPlist))
  170.          ;;设置新生成多段线的各property值
  171.          (VLA-PUT-CLOSED objNew entClose)
  172.          (VLA-PUT-LAYER objNew entLayer)
  173.          (VLA-PUT-LINETYPE objNew entLinet)
  174.          (VLA-PUT-LINETYPESCALE objNew entLines)
  175.          (VLA-PUT-LINEWEIGHT objNew entLinew)
  176.          (VLA-PUT-THICKNESS objNew entThick)
  177.          (VLA-PUT-TRUECOLOR objNew entTruec)
  178.          (VLA-PUT-ELEVATION objNew entEleva)
  179.          (VLA-PUT-CONSTANTWIDTH objNew entConwidth)
  180.          (VLA-PUT-LINETYPEGENERATION objNew entLTGen)
  181.          ;;赋值完成,更新对象
  182.          (VLA-UPDATE objNew)
  183.          (SETQ retuValue T)
  184.        ) ;_ 结束progn
  185.        (PROGN (PRINT "您选择的不是多段线!")
  186.               (SETQ retuValue nil)
  187.        ) ;_ 结束progn
  188.     ) ;_ 结束IF

  189.     (PRINT)
  190.     (SETQ p (CAR (CDR (ENTSEL "\n请选择要移除的顶点:"))))
  191.   ) ;_ 结束while
  192.   (PRINC "\n 本条多段线现有:")
  193.   (PRINC (- (/ nuLen 2) 1))
  194.   (PRINC "个顶点......谢谢使用!")
  195.   (PRINC)
  196. ) ;_ 结束defun



  197. ;;;--------------------------------------------------------
  198. ;;;函数: getPlList                               
  199. ;;;--------------------------------------------------------
  200. ;;;说明:本函数提取多段线的各端点坐标值构成一张表并返回
  201. ;;;               
  202. ;;;               
  203. ;;;编制者:高老师               
  204. ;;;--------------------------------------------------------

  205. (DEFUN getPlList (#entity / OBJ LW_T8 OBJ_1)
  206.   (SETQ obj (ENTGET #entity))
  207.   (SETQ lw_t8 (CDR (ASSOC 8 obj)))
  208.   (SETQ obj_1 nil)
  209.   (WHILE (/= (ASSOC 10 obj) nil)
  210.     (IF        (AND (= (CAAR obj) 10)
  211.              (NOT (EQUAL (CDAR obj) (LAST obj_1) 0.001))
  212.         ) ;_ 结束and
  213.       (SETQ obj_1 (APPEND obj_1 (LIST (CDAR obj))))
  214.     )                                        ;生成坐标表同时去掉相邻重点,不带10
  215.     (SETQ obj (CDR obj))
  216.   ) ;_ 结束while
  217.   (SETQ obj obj_1)
  218.   (IF (EQUAL (CAR obj) (LAST obj) 0.001)
  219.     (SETQ obj (REVERSE (CDR (REVERSE obj))))
  220.   ) ;_ 结束if
  221.   ;;判断首闭
  222.   (SETQ #temp obj)
  223. ) ;_ 结束defun
  224. ;;end defun



  225. ;;;--------------------------------------------------------
  226. ;;;函数: c:CC                       
  227. ;;;--------------------------------------------------------
  228. ;;;编制日期:2006.4.1
  229. ;;;编制者  :何俊
  230. ;;;函数说明:本函数用以模拟ACAD2006中的复制命令,其实就是默认为多重复制
  231. ;;;--------------------------------------------------------
  232. (DEFUN c:cc ()
  233.   (PRINC "选择对象:")
  234.   (SETQ ss1 (SSGET))
  235.   (COMMAND "copy")
  236.   (COMMAND ss1)
  237.   (COMMAND "")
  238.   (COMMAND "M")
  239. ) ;_ 结束defun

  240. ;;;--------------------------------------------------------
  241. ;;;函数: c:SW
  242. ;;;--------------------------------------------------------
  243. ;;;编制日期:2006.4.1
  244. ;;;编制者  :何俊
  245. ;;;函数说明:本函数选择用户指定多边形内的实体(注意多边形要在当前视口内)。
  246. ;;;--------------------------------------------------------
  247. (DEFUN c:sw (/ ENAME #MYLIST SS1)
  248.   (princ "\n 选择用户指定多边形内的实体(注意多边形要在当前视口内)。")
  249.   (SETQ ename (CAR (ENTSEL "\n请选择一个多边形:")))
  250.   (SETQ #mylist (getpllist ename))
  251.   (SETQ ss1 (SSGET "_WP" #mylist))
  252.   (SSSETFIRST NIL ss1)
  253.   (SETQ ss1 ss1)
  254. ) ;_ 结束defun
  255. ;;;--------------------------------------------------------
  256. ;;;函数: c:CW
  257. ;;;--------------------------------------------------------
  258. ;;;编制日期:2006.4.1
  259. ;;;编制者  :何俊
  260. ;;;函数说明:本函数选择用户指定多边形内以及与多边形相交的实体
  261. ;;;         (注意多边形要在当前视口内)。
  262. ;;;--------------------------------------------------------
  263. (DEFUN c:cw (/ ENAME #MYLIST SS1)
  264.   (princ "\n 选择用户指定多边形内以及与多边形相交的实体(注意多边形要在当前视口内)")
  265.   (SETQ ename (CAR (ENTSEL "\n请选择一个多边形:")))
  266.   (SETQ #mylist (getpllist ename))
  267.   (SETQ ss1 (SSGET "_CP" #mylist))
  268.   (SSSETFIRST NIL ss1)
  269.   (SETQ ss1 ss1)
  270. ) ;_ 结束defun


  271. ;;;--------------------------------------------------------
  272. ;;;函数: c:es
  273. ;;;--------------------------------------------------------
  274. ;;;编制日期:2006.4.
  275. ;;;编制者  :何俊
  276. ;;;函数说明:本函数选择用户指定多边形外的实体(注意多边形要在当前视口内)。
  277. ;;;--------------------------------------------------------

  278. (DEFUN c:es (/ ename #mylist ss1)
  279.   (princ "\n 选择用户指定多边形外的实体(注意多边形要在当前视口内)。")
  280.   (SETQ ename (CAR (ENTSEL "\n请选择一个多边形:")))
  281.   (SETQ #mylist (getpllist ename))
  282.   (SETQ ss1 (SSGET "_WP" #mylist))
  283.   (COMMAND "select" "all" "r")
  284.   (COMMAND ss1)
  285.   (COMMAND "")
  286.   (SETQ ss1 (SSGET "_p"))
  287.   (SSSETFIRST NIL ss1)
  288.   (SETQ ss1 ss1)

  289. ) ;_ 结束defun
  290. ;;;--------------------------------------------------------
  291. ;;;函数: c:Cs
  292. ;;;--------------------------------------------------------
  293. ;;;编制日期:2006.4.
  294. ;;;编制者  :何俊
  295. ;;;函数说明:本函数选择用户指定多边形外且不与多边形相交实体
  296. ;;;         (注意多边形要在当前视口内)。
  297. ;;;--------------------------------------------------------

  298. (DEFUN c:Cs (/ ename #mylist ss1)
  299.   (princ "\n 选择用户指定多边形外且不与多边形相交实体(注意多边形要在当前视口内)")
  300.   (SETQ ename (CAR (ENTSEL "\n请选择一个多边形:")))
  301.   (SETQ #mylist (getpllist ename))
  302.   (SETQ ss1 (SSGET "_cP" #mylist))
  303.   (COMMAND "select" "all" "r")
  304.   (COMMAND ss1)
  305.   (COMMAND "")
  306.   (SETQ ss1 (SSGET "_p"))
  307.   (SSSETFIRST NIL ss1)
  308.   (SETQ ss1 ss1)

  309. ) ;_ 结束defun






应朋友的要求编了一个去除完全平直的多段线中间的顶点的程序,也许有朋友也能够用到
;;;--------------------------------------------------------
;;;函数: C:frank                               
;;;--------------------------------------------------------
;;;来源:            作者: 何俊
;;;编制时间:2006.4.
;;;功能:     移除多段线上完全平直的段上的顶点
;;;语法:     frank
;;;参数      
;;;返回值:   成功T    nil
;;;备注  :   本程序调用了上面移除顶点程序中的一些子程序,因此需要先加载上面的子程序
;;;               这个程序才能使用
;;;--------------------------------------------------------
(DEFUN c:frank (/          name            #pl1      #pl2        %ver
                %id          p1            p2              p3        ang1
                ang2          array1    #plist    vaPlist        obj
                objnew          entClose  entLayer  entLinet        entLines
                entLinew  entThick  entTruec  entEleva        entConwidth
                entLTGen  $a
               )
  (SETQ name (CAR (ENTSEL "\n<请选择多段线>:")))
  ;;要增加判断是否是多段线的语句
  (IF (= (CDR (ASSOC 0 (ENTGET name))) "LWPOLYLINE")
    (PROGN
      ;;调用子程序取出多段线所有顶点的坐标集合
      (SETQ #pl1 (getplList name))
      ;;求出顶点个数%ver,确定循环次数%ver-2,移除的原则:
      ;;求每个点和上一个点构成的角度以及和下一个点构成的角度,若相等则说明是完全平直的
      ;;将中间点滤去。以此类推。
      (SETQ %ver (LENGTH #PL1))
      (SETQ %id 1)
      (SETQ #pl2 nil)
      ;;加入多段线第一点的坐标,无论多段线中间有多少完全平直的点,首尾点是始终要的
      (SETQ #pl2 (APPEND #pl2 (NTH 0 #pl1)))
      (REPEAT (- %ver 2)
        ;;依次提取三个点,计算第一点到第二点的角度ANG1,与第二点到第三点角度ANG2进行比较,若相等
        ;;则说明三点共线,滤去p2点
        (SETQ p1 (NTH (- %id 1) #pl1))
        (SETQ p2 (NTH %id #pl1))
        (SETQ p3 (NTH (+ %id 1) #pl1))
        (SETQ ang1 (ANGLE p1 p2))
        (SETQ ang2 (ANGLE p2 p3))
        ;;为什么要用EQUAL而不用“=”呢,因当用PE命令在直线上加点后,再用“=”比较p1->p2与p2->p3的角度
        ;;所得结果为NIL,即不相等,因此用EQUAL且将最大允许误差定为小数点后7位,这个值可以根据实际需要
        ;;进行修改
        (IF (NOT (EQUAL ang1 ang2 0.0000001))
          (SETQ #pl2 (APPEND #pl2 (NTH %id #pl1)))
        ) ;_ 结束if
        (SETQ %id (+ 1 %id))
      ) ;_ 结束repeat
      ;;加入最后一个点
      (SETQ #pl2 (APPEND #pl2 (NTH (- %ver 1) #pl1)))

;;;  (SETQ %id 0)
;;;  (SETQ #pl3 nil)
;;;  (REPEAT (LENGTH #pl2)
;;;    (SETQ #pl3 (APPEND #pl3 (CAR (NTH %id #pl2))))
;;;    (SETQ #pl3 (APPEND #pl3 (CADR (NTH %id #pl2))))
;;;    (setq %id (+ %id 1))
;;;  ) ;_ 结束repeat
      ;;以下涉及VLISP的内容
      ;;计算数组上下标
      (SETQ array1 (CONS 0 (- (LENGTH #pl2) 1)))
      (SETQ #plist (VLAX-MAKE-SAFEARRAY VLAX-VBDOUBLE array1))
      (VLAX-SAFEARRAY-FILL #Plist #pl2)
      ;;由数组生成变体
      (SETQ vaPlist (VLAX-MAKE-VARIANT #Plist))

      (SETQ obj (VLAX-ENAME->VLA-OBJECT Name))

      ;;删除旧线,换上新线.要匹配的项目有
      ;;Closed......闭合    Layer.........图层
      ;;Linetype....线型    LinetypeScale.线型缩放比例
      ;;Lineweight..线宽    PlotStyleName.打印样式名
      ;;Thickness...厚度    TrueColor.....颜色
      (SETQ entClose        (VLA-GET-CLOSED obj)
            entLayer        (VLA-GET-LAYER obj)
            entLinet        (VLA-GET-LINETYPE obj)
            entLines        (VLA-GET-LINETYPESCALE obj)
            entLinew        (VLA-GET-LINEWEIGHT obj)
            entThick        (VLA-GET-THICKNESS obj)
            entTruec        (VLA-GET-TRUECOLOR obj)
            entEleva        (VLA-GET-ELEVATION obj)
            entConwidth        (VLA-GET-CONSTANTWIDTH obj) ;_全局宽度
            entLTGen        (VLA-GET-LINETYPEGENERATION obj) ;_线型生成
      ) ;_ 结束setq
      (ENTDEL Name)
      (SETQ objNew (VLA-ADDLIGHTWEIGHTPOLYLINE (model-space) vaPlist))
      ;;设置新生成多段线的各property值
      (VLA-PUT-CLOSED objNew entClose)
      (VLA-PUT-LAYER objNew entLayer)
      (VLA-PUT-LINETYPE objNew entLinet)
      (VLA-PUT-LINETYPESCALE objNew entLines)
      (VLA-PUT-LINEWEIGHT objNew entLinew)
      (VLA-PUT-THICKNESS objNew entThick)
      (VLA-PUT-TRUECOLOR objNew entTruec)
      (VLA-PUT-ELEVATION objNew entEleva)
      (VLA-PUT-CONSTANTWIDTH objNew entConwidth)
      (VLA-PUT-LINETYPEGENERATION objNew entLTGen)
      ;;赋值完成,更新对象
      (VLA-UPDATE objNew)
      (SETQ $a (STRCAT "\n ...处理完成! 处理前点数: "
                       (ITOA %ver)
                       " 处理后点数: "
                       (ITOA (/ (LENGTH #pl2) 2))
                       " !"
               ) ;_ 结束STRCAT
      ) ;_ 结束setq
      (PRINC $a)
      (SETQ retuValue T)
    ) ;_ 结束progn
    (PROGN
      (PRINC "\n 选择的不是多段线!")
      (SETQ retuValue nil)
    ) ;_ 结束progn

  ) ;_ 结束if
  (PRINC)
) ;_ 结束defun


;;;--------------------------------------------------------
;;;函数: getPlList                               
;;;--------------------------------------------------------
;;;说明:本函数提取多段线的各端点坐标值构成一张表并返回
;;;               
;;;               
;;;编制者:高老师               
;;;--------------------------------------------------------

(DEFUN getPlList (#entity)
  (SETQ obj (ENTGET #entity))
  (SETQ lw_t8 (CDR (ASSOC 8 obj)))
  (SETQ obj_1 nil)
  (WHILE (/= (ASSOC 10 obj) nil)
    (IF        (AND (= (CAAR obj) 10)
             (NOT (EQUAL (CDAR obj) (LAST obj_1) 0.001))
        ) ;_ 结束AND
      (SETQ obj_1 (APPEND obj_1 (LIST (CDAR obj))))
    )                                        ;生成坐标表同时去掉相邻重点,不带10
    (SETQ obj (CDR obj))
  ) ;_ 结束WHILE
  (SETQ obj obj_1)
  (IF (EQUAL (CAR obj) (LAST obj) 0.001)
    (SETQ obj (REVERSE (CDR (REVERSE obj))))
  ) ;_ 结束IF
  ;;判断首闭
  (SETQ #temp obj)
) ;_ 结束DEFUN
;;end defun
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2006-4-7 11:45:53 | 显示全部楼层
编程习惯很好,顶一下
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-4-8 19:39:04 | 显示全部楼层
谢谢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-4-10 00:43:42 | 显示全部楼层
那个减少PL线点的程序如果能改成不用选择PL线直接用框选减点就更好了 因为有时候要一起减少好几个点呢 而且框选我感觉也能更方便些  只是我个人意见    不过很佩服楼主了  我只懂得一点这方面的东西   真的好希望能跟你好好学习一下
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-4-13 10:10:36 | 显示全部楼层
楼主做得很不错,我在学LISP,VLISP还有些不懂
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-4-30 19:04:15 | 显示全部楼层
谢谢各位的支持
因为我没有足够多的时间上网,所以不能及时地表示我的谢意哈
窗选的建议,想了一下,是可以实现的.等我回去编过!
应朋友的要求编了一个去除完全平直的多段线中间的顶点的程序,也许有朋友也能够用到
;;;--------------------------------------------------------
;;;函数: C:frank                               
;;;--------------------------------------------------------
;;;来源:            作者: 何俊
;;;编制时间:2006.4.
;;;功能:     移除多段线上完全平直的段上的顶点
;;;语法:     frank
;;;参数      
;;;返回值:   成功T    nil
;;;备注  :   本程序调用了上面移除顶点程序中的一些子程序,因此需要先加载上面的子程序
;;;               这个程序才能使用
;;;--------------------------------------------------------
(DEFUN c:frank (/          name            #pl1      #pl2        %ver
                %id          p1            p2              p3        ang1
                ang2          array1    #plist    vaPlist        obj
                objnew          entClose  entLayer  entLinet        entLines
                entLinew  entThick  entTruec  entEleva        entConwidth
                entLTGen  $a
               )
  (SETQ name (CAR (ENTSEL "\n<请选择多段线>:")))
  ;;要增加判断是否是多段线的语句
  (IF (= (CDR (ASSOC 0 (ENTGET name))) "LWPOLYLINE")
    (PROGN
      ;;调用子程序取出多段线所有顶点的坐标集合
      (SETQ #pl1 (getplList name))
      ;;求出顶点个数%ver,确定循环次数%ver-2,移除的原则:
      ;;求每个点和上一个点构成的角度以及和下一个点构成的角度,若相等则说明是完全平直的
      ;;将中间点滤去。以此类推。
      (SETQ %ver (LENGTH #PL1))
      (SETQ %id 1)
      (SETQ #pl2 nil)
      ;;加入多段线第一点的坐标,无论多段线中间有多少完全平直的点,首尾点是始终要的
      (SETQ #pl2 (APPEND #pl2 (NTH 0 #pl1)))
      (REPEAT (- %ver 2)
        ;;依次提取三个点,计算第一点到第二点的角度ANG1,与第二点到第三点角度ANG2进行比较,若相等
        ;;则说明三点共线,滤去p2点
        (SETQ p1 (NTH (- %id 1) #pl1))
        (SETQ p2 (NTH %id #pl1))
        (SETQ p3 (NTH (+ %id 1) #pl1))
        (SETQ ang1 (ANGLE p1 p2))
        (SETQ ang2 (ANGLE p2 p3))
        ;;为什么要用EQUAL而不用“=”呢,因当用PE命令在直线上加点后,再用“=”比较p1->p2与p2->p3的角度
        ;;所得结果为NIL,即不相等,因此用EQUAL且将最大允许误差定为小数点后7位,这个值可以根据实际需要
        ;;进行修改
        (IF (NOT (EQUAL ang1 ang2 0.0000001))
          (SETQ #pl2 (APPEND #pl2 (NTH %id #pl1)))
        ) ;_ 结束if
        (SETQ %id (+ 1 %id))
      ) ;_ 结束repeat
      ;;加入最后一个点
      (SETQ #pl2 (APPEND #pl2 (NTH (- %ver 1) #pl1)))

;;;  (SETQ %id 0)
;;;  (SETQ #pl3 nil)
;;;  (REPEAT (LENGTH #pl2)
;;;    (SETQ #pl3 (APPEND #pl3 (CAR (NTH %id #pl2))))
;;;    (SETQ #pl3 (APPEND #pl3 (CADR (NTH %id #pl2))))
;;;    (setq %id (+ %id 1))
;;;  ) ;_ 结束repeat
      ;;以下涉及VLISP的内容
      ;;计算数组上下标
      (SETQ array1 (CONS 0 (- (LENGTH #pl2) 1)))
      (SETQ #plist (VLAX-MAKE-SAFEARRAY VLAX-VBDOUBLE array1))
      (VLAX-SAFEARRAY-FILL #Plist #pl2)
      ;;由数组生成变体
      (SETQ vaPlist (VLAX-MAKE-VARIANT #Plist))

      (SETQ obj (VLAX-ENAME->VLA-OBJECT Name))

      ;;删除旧线,换上新线.要匹配的项目有
      ;;Closed......闭合    Layer.........图层
      ;;Linetype....线型    LinetypeScale.线型缩放比例
      ;;Lineweight..线宽    PlotStyleName.打印样式名
      ;;Thickness...厚度    TrueColor.....颜色
      (SETQ entClose        (VLA-GET-CLOSED obj)
            entLayer        (VLA-GET-LAYER obj)
            entLinet        (VLA-GET-LINETYPE obj)
            entLines        (VLA-GET-LINETYPESCALE obj)
            entLinew        (VLA-GET-LINEWEIGHT obj)
            entThick        (VLA-GET-THICKNESS obj)
            entTruec        (VLA-GET-TRUECOLOR obj)
            entEleva        (VLA-GET-ELEVATION obj)
            entConwidth        (VLA-GET-CONSTANTWIDTH obj) ;_全局宽度
            entLTGen        (VLA-GET-LINETYPEGENERATION obj) ;_线型生成
      ) ;_ 结束setq
      (ENTDEL Name)
      (SETQ objNew (VLA-ADDLIGHTWEIGHTPOLYLINE (model-space) vaPlist))
      ;;设置新生成多段线的各property值
      (VLA-PUT-CLOSED objNew entClose)
      (VLA-PUT-LAYER objNew entLayer)
      (VLA-PUT-LINETYPE objNew entLinet)
      (VLA-PUT-LINETYPESCALE objNew entLines)
      (VLA-PUT-LINEWEIGHT objNew entLinew)
      (VLA-PUT-THICKNESS objNew entThick)
      (VLA-PUT-TRUECOLOR objNew entTruec)
      (VLA-PUT-ELEVATION objNew entEleva)
      (VLA-PUT-CONSTANTWIDTH objNew entConwidth)
      (VLA-PUT-LINETYPEGENERATION objNew entLTGen)
      ;;赋值完成,更新对象
      (VLA-UPDATE objNew)
      (SETQ $a (STRCAT "\n ...处理完成! 处理前点数: "
                       (ITOA %ver)
                       " 处理后点数: "
                       (ITOA (/ (LENGTH #pl2) 2))
                       " !"
               ) ;_ 结束STRCAT
      ) ;_ 结束setq
      (PRINC $a)
      (SETQ retuValue T)
    ) ;_ 结束progn
    (PROGN
      (PRINC "\n 选择的不是多段线!")
      (SETQ retuValue nil)
    ) ;_ 结束progn

  ) ;_ 结束if
  (PRINC)
) ;_ 结束defun


;;;--------------------------------------------------------
;;;函数: getPlList                               
;;;--------------------------------------------------------
;;;说明:本函数提取多段线的各端点坐标值构成一张表并返回
;;;               
;;;               
;;;编制者:高老师               
;;;--------------------------------------------------------

(DEFUN getPlList (#entity)
  (SETQ obj (ENTGET #entity))
  (SETQ lw_t8 (CDR (ASSOC 8 obj)))
  (SETQ obj_1 nil)
  (WHILE (/= (ASSOC 10 obj) nil)
    (IF        (AND (= (CAAR obj) 10)
             (NOT (EQUAL (CDAR obj) (LAST obj_1) 0.001))
        ) ;_ 结束AND
      (SETQ obj_1 (APPEND obj_1 (LIST (CDAR obj))))
    )                                        ;生成坐标表同时去掉相邻重点,不带10
    (SETQ obj (CDR obj))
  ) ;_ 结束WHILE
  (SETQ obj obj_1)
  (IF (EQUAL (CAR obj) (LAST obj) 0.001)
    (SETQ obj (REVERSE (CDR (REVERSE obj))))
  ) ;_ 结束IF
  ;;判断首闭
  (SETQ #temp obj)
) ;_ 结束DEFUN
;;end defun
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 918个

财富等级: 财运亨通

发表于 2006-7-2 15:02:57 | 显示全部楼层
为什么添加顶点不见了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-2 18:30:12 | 显示全部楼层
这个函数有很多缺陷:比如当多段线各段的宽度不一样时,加点的话宽度会改变.....因一直以来工作都很忙,没有时间去完善,还请楼主谅解啦

  1.   [FONT=courier new]
  2. ;;;-------------------------------------------
  3. ;;;函数名:AddVertex       
  4. ;;;-------------------------------------------
  5. ;;;来源:     作(译)者:   
  6. ;;;编制时间:2006.3.29-30
  7. ;;;功能  :添加/删除多段线顶点
  8. ;;;语法  :(AddVertex ename p)
  9. ;;;参数  :ename...图元名  p...点
  10. ;;;返回值:成功....T    失败...nil
  11. ;;;备注  :还应添加将老式多段线转换为轻便多段线的功能
  12. ;;;       还未加入删除点的功能还是另写一个吧
  13. ;;;-------------------------------------------
  14. (DEFUN c:addvertex (/              ename        obj          objNew    plobj
  15.                     pp              n                plist          nuelev    nuVertex
  16.                     array1    #plist        nulen          nux            nuid
  17.                     #templ    vaplist        entclose  entlinet  entlines
  18.                     entlinew  entthick        enttruec  entconwidth
  19.                    )
  20.   (princ "\n AddVertex......在多段线上加点(2006.3)")
  21.   (SETQ ss1 (ENTSEL "\n请选择一条多段线:"))
  22.   (SETQ eName (CAR ss1))
  23.   (SETQ p (GETPOINT "请选择插入点:"))
  24.   (SETQ obj (VLAX-ENAME->VLA-OBJECT eName))
  25.   (WHILE p
  26.     (IF        objNew
  27.       (SETQ obj objNew)
  28.     ) ;_ 结束if
  29.     (IF
  30.       (WCMATCH
  31.         (VLA-GET-OBJECTNAME obj)
  32.         "LWPOLYLINE,AcDbPolyline"
  33.       ) ;_ 结束wcmatch
  34.        (PROGN
  35.          (SETQ pp (VLAX-CURVE-GETCLOSESTPOINTTO obj (TRANS p 1 0)))
  36.          ;;取FIX后,n的值始终是该多段线前进方向的前一个点,
  37.          ;;加1后,表示点P成为继该点后的下一个点即n+1个顶点
  38.          (SETQ n (+ (FIX (VLAX-CURVE-GETPARAMATPOINT obj pp)) 1))
  39.          (SETQ Plist
  40.                 (VLAX-SAFEARRAY->LIST
  41.                   (VLAX-VARIANT-VALUE
  42.                     (VLA-GET-COORDINATES obj)
  43.                   ) ;_ 结束vlax-variant-value
  44.                 ) ;_ 结束vlax-safearray->list
  45.          ) ;_ 结束setq
  46.          ;;求算数组上下标,先求出Vertex的数目
  47.          (SETQ nuVertex (+ (FIX (VLAX-CURVE-GETENDPARAM obj)) 1))
  48.          ;;若多段线为闭合的,通过上行语句求出的Vertex数目将会多一个
  49.          ;;在下面的判断语句中减去
  50.          (if (= (vla-get-Closed obj) :vlax-true)
  51.            (setq nuVertex (- nuVertex 1))
  52.            )
  53.          ;;计算数组上下标,因轻便多段线只需XY故改为
  54.          (SETQ array1 (CONS 0 (- (* (+ nuVertex 1) 2) 1)))
  55.          (SETQ #plist (VLAX-MAKE-SAFEARRAY VLAX-VBDOUBLE array1))
  56.          ;;计算顶点表内元素个数(主要是担心会不会出现Z值未被忽略的情况)
  57.          (SETQ nuLen (LENGTH Plist))
  58.          ;;(SETQ nux (/ nulen nuVertex))
  59.          ;;根据n值,将点P的坐标插入到Plist中,先将Plist转为XYZ样式
  60.          (SETQ nuID 0)
  61.          (SETQ #templ nil)
  62.          ;;因为是轻便多段线只要XY所以只需简单地加入P点坐标即可
  63.          ;;当用户点取了超过了最后一点时(不是在最后一点和次点之间)
  64.          ;;点P的坐标不能通过下面的REPEAT语句加入到LIST中去,
  65.          ;;因此,在REPEAT之后单独再写一个语句。
  66.          (REPEAT nuLen
  67.            (IF (= nuID (* n 2))
  68.              (SETQ #templ (APPEND #templ (LIST (CAR p) (CADR p))))
  69.            ) ;_ 结束if
  70.            (SETQ #templ (APPEND #templ (LIST (NTH nuID Plist))))
  71.            (SETQ nuID (+ 1 nuID))
  72.          ) ;_ 结束repeat
  73.          (IF (= nuLen (* n 2))
  74.            (SETQ #templ (APPEND #templ (LIST (CAR p) (CADR p))))
  75.          ) ;_ 结束if
  76.          (VLAX-SAFEARRAY-FILL #Plist #temPl)
  77.          ;;由数组生成变体
  78.          (SETQ vaPlist (VLAX-MAKE-VARIANT #Plist))
  79.          ;;删除旧线,换上新线.要匹配的项目有
  80.          ;;Closed......闭合    Layer.........图层
  81.          ;;Linetype....线型    LinetypeScale.线型缩放比例
  82.          ;;Lineweight..线宽    PlotStyleName.打印样式名
  83.          ;;Thickness...厚度    TrueColor.....颜色
  84.          (SETQ entClose           (VLA-GET-CLOSED obj)
  85.                entLayer           (VLA-GET-LAYER obj)
  86.                entLinet           (VLA-GET-LINETYPE obj)
  87.                entLines           (VLA-GET-LINETYPESCALE obj)
  88.                entLinew           (VLA-GET-LINEWEIGHT obj)
  89.                entThick           (VLA-GET-THICKNESS obj)
  90.                entTruec           (VLA-GET-TRUECOLOR obj)
  91.                entEleva           (VLA-GET-ELEVATION obj)
  92.                entConwidth (VLA-GET-CONSTANTWIDTH obj) ;_全局宽度
  93.                entLTGen           (VLA-GET-LINETYPEGENERATION obj) ;_线型生成

  94.          ) ;_ 结束setq
  95.          ;;删除原来的线
  96.          (SETQ eName (VLAX-VLA-OBJECT->ENAME obj))
  97.          (ENTDEL eName)
  98.          (SETQ objNew (VLA-ADDLIGHTWEIGHTPOLYLINE (model-space) vaPlist))
  99.          ;;设置新生成多段线的各property值
  100.          (VLA-PUT-CLOSED objNew entClose)
  101.          (VLA-PUT-LAYER objNew entLayer)
  102.          (VLA-PUT-LINETYPE objNew entLinet)
  103.          (VLA-PUT-LINETYPESCALE objNew entLines)
  104.          (VLA-PUT-LINEWEIGHT objNew entLinew)
  105.          (VLA-PUT-THICKNESS objNew entThick)
  106.          (VLA-PUT-TRUECOLOR objNew entTruec)
  107.          (VLA-PUT-ELEVATION objNew entEleva)
  108.          (VLA-PUT-CONSTANTWIDTH objNew entConwidth)
  109.          (VLA-PUT-LINETYPEGENERATION objNew entLTGen)
  110.          ;;赋值完成,更新对象
  111.          (VLA-UPDATE objNew)
  112.          (SETQ retuValue T)
  113.        ) ;_ 结束progn
  114.        (PRINT "您选择的不是多段线!")

  115.     ) ;_ 结束if
  116.     (PRINT)
  117.     (SETQ p (GETPOINT "请选择插入点:"))
  118.   ) ;_ 结束while
  119.   (princ "\n 本条多段线现有:")
  120.   (princ (+ (/ nuLen 2) 1))
  121.   (princ "个顶点......谢谢使用!")
  122.   (PRINC)
  123. ) ;_ 结束defun
  124.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-6-14 09:43:20 | 显示全部楼层
呵呵,多段线删除顶点程序,正需要研究呢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-7-5 14:07:41 | 显示全部楼层
何俊的删除和添加多段线顶点程序:lol
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 720个

财富等级: 财运亨通

发表于 2016-5-30 20:01:12 | 显示全部楼层
好程序  必须支持了   
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-27 14:23 , Processed in 0.332718 second(s), 52 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表