找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 6489|回复: 16

[原创] 参考eachy的算法做的交点处批量断开程序

[复制链接]

已领礼包: 24个

财富等级: 恭喜发财

发表于 2006-1-25 14:41:46 | 显示全部楼层 |阅读模式

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

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

×
说明:
1。调用entmake生成line,arc,ellipse
2。本程序未调用break命令,故暂不考虑pline线的处理
3。因为用了vla-intersectwith函数,对于纯直线集建议另采用直线断点程序以提高速度。
4。本程序参考了很多人的设计思路,在此一并感谢,不一一提到,也希望大家帮忙看看,提一些改进意见

  1. ;;主函数
  2. (defun c:MB (/ elist ssg n t0)
  3.   (VL-LOAD-COM)
  4.   (setq t0 (xdl-getutime))
  5.   (if (setq ssg (ssget '((0 . "line,arc,circle,ellipse"))))
  6.     (vlax-for obj (vla-get-activeselectionset
  7.                     (vla-get-activedocument (vlax-get-acad-object))
  8.                   )
  9.       (setq elist (cons obj elist))        ; ssg->elist
  10.     )
  11.   )
  12.   (DoEntMake (InterSort (ssinter elist)))
  13.   (princ (strcat "\n*****找到交点"
  14.                  (itoa n)
  15.                  "个,交点断开操作共耗时"
  16.                  (rtos (- (xdl-getutime) t0) 2 3)
  17.                  "秒。*****"
  18.          )
  19.   )
  20.   (princ)
  21. )

  22. ;;求交点集函数-nth
  23. ;;经过测试,nth函数仅比assoc函数快一点点。
  24. ;;故此函数也可取消i,j变量,直接使用assoc函数
  25. (defun ssinter (el / el1 obj1 obj2 ipts pts list1 outlst i j)
  26.   (setq        outlst (mapcar 'list el)
  27.         i      -1                        ;obj1位置指针
  28.         n      0                        ;交点数计数器
  29.   )
  30.   (while el
  31.     (setq obj1        (car el)
  32.           list1        (nth (setq i (1+ i)) outlst) ;obj1已有的交点列表
  33.           el        (cdr el)
  34.           el1        el
  35.           j        i                        ;obj2位置指针
  36.     )
  37.     (while el1
  38.       (setq obj2 (car el1)
  39.             el1         (cdr el1)
  40.             j         (1+ j)
  41.       )
  42.       ;;取交点
  43.       (if (and (setq ipts (vla-intersectwith obj1 obj2 0))
  44.                (setq ipts (vlax-variant-value ipts))
  45.                (> (vlax-safearray-get-u-bound ipts 1) 0)

  46.           )
  47.         (progn
  48.           (setq        ipts (vlax-safearray->list ipts)
  49.                 pts  '()                ;obj1,obj2交点临时列表变量
  50.           )
  51.           (while (> (length ipts) 0)
  52.             (setq pts  (cons (list (car ipts)
  53.                                    (cadr ipts)
  54.                                    (caddr ipts)
  55.                              )
  56.                              pts
  57.                        )
  58.                   ipts (cdddr ipts)
  59.             )
  60.           )
  61.           (setq        list1 (append list1 pts) ;存obj1交点表,循环结束后再更新
  62.                 n     (+ n (length pts)) ;交点计数累加
  63.           )
  64.           ;;obj2的交点列表立即更新
  65.           (setq
  66.             outlst (subst (append (nth j outlst) pts)
  67.                           (nth j outlst)
  68.                           outlst
  69.                    )
  70.           )
  71.         )
  72.       )
  73.     )
  74.     ;;当obj1存在交点,且非封闭曲线,添加两端点
  75.     (if        (and (cdr list1) (not (vlax-curve-isClosed obj1)))
  76.       (setq list1 (append list1
  77.                           (list (vlax-curve-getEndPoint obj1))
  78.                           (list (vlax-curve-getStartPoint obj1))
  79.                   )
  80.       )
  81.     )
  82.     (setq outlst (subst list1 (nth i outlst) outlst)) ;更新obj1交点列表
  83.   )
  84.   outlst
  85. )

  86. ;;点集排序及删除重复点函数
  87. (defun InterSort (el / obj1 pts plst outlst)
  88.   (setq outlst '())                        ;empty list
  89.   (foreach item        el
  90.     (setq obj1 (car item)
  91.           pts  (cdr item)
  92.           plst '()                        ;empty list
  93.     )
  94.     (if        pts                                ;若无交点,则不修改该实体
  95.       (progn
  96.         ;;交点排序,列表为逆序
  97.         (setq
  98.           pts (vl-sort
  99.                 pts
  100.                 (function (lambda (p1 p2)
  101.                             (< (vlax-curve-getParamAtPoint obj1 p1)
  102.                                (vlax-curve-getParamAtPoint obj1 p2)
  103.                             )
  104.                           )
  105.                 )
  106.               )
  107.         )
  108.         ;;剔除重复点并将列表顺序转正
  109.         (foreach p pts
  110.           (if plst
  111.             (if        (not (equal p (car plst) 0.00001))
  112.               (setq plst (cons p plst))
  113.             )
  114.             (setq plst (cons p plst))
  115.           )
  116.         )
  117.         ;;闭合曲线需再添加首个交点以使新实体完全封闭
  118.         (if (vlax-curve-isClosed obj1)
  119.           (setq plst (cons (last plst) plst))
  120.         )
  121.         (setq plst   (cons (vlax-vla-object->ename obj1) plst)
  122.               outlst (cons plst outlst)
  123.         )

  124.       )
  125.     )
  126.   )
  127.   outlst
  128. )

  129. ;;调用entmake生成新实体
  130. (defun DoEntMake (el / obj objlst objname objcen objratio objaxis)
  131.   (foreach e el
  132.     (setq obj          (car e)
  133.           objlst  (entget obj)
  134.           objlst  (vl-remove (assoc -1 objlst) objlst) ;去除图元名
  135.           objlst  (vl-remove (assoc 330 objlst) objlst) ;去除id
  136.           objlst  (vl-remove (assoc 5 objlst) objlst) ;去除句柄
  137.           objname (cdr (assoc 0 objlst))
  138.     )
  139.     (cond
  140.       ((= objname "LINE")
  141.        (repeat (- (length e) 2)
  142.          (setq e (cdr e))
  143.          (setq objlst (subst (cons 10 (car e)) (assoc 10 objlst) objlst))
  144.          (setq objlst (subst (cons 11 (cadr e)) (assoc 11 objlst) objlst))
  145.          (entmake objlst)
  146.        )
  147.        (entdel obj)
  148.       )
  149.       ((= objname "CIRCLE")
  150.        (setq objcen (cdr (assoc 10 objlst)))
  151.        (setq objlst (subst (cons 0 "ARC") (assoc 0 objlst) objlst))
  152.        (setq objlst (append objlst
  153.                             (list (cons 100 "AcDbArc")
  154.                                   (cons 50 0.0)
  155.                                   (cons 51 0.0)
  156.                             )
  157.                     )
  158.        )
  159.        (repeat (- (length e) 2)
  160.          (setq e (cdr e))
  161.          (setq objlst (subst (cons 50 (angle objcen (cadr e)))
  162.                              (assoc 50 objlst)
  163.                              objlst
  164.                       )
  165.          )
  166.          (setq objlst (subst (cons 51 (angle objcen (car e)))
  167.                              (assoc 51 objlst)
  168.                              objlst
  169.                       )
  170.          )
  171.          (entmake objlst)
  172.        )
  173.        (entdel obj)
  174.       )
  175.       ((= objname "ARC")
  176.        (setq objcen (cdr (assoc 10 objlst)))
  177.        (repeat (- (length e) 2)
  178.          (setq e (cdr e))
  179.          (setq objlst (subst (cons 50 (angle objcen (cadr e)))
  180.                              (assoc 50 objlst)
  181.                              objlst
  182.                       )
  183.          )
  184.          (setq objlst (subst (cons 51 (angle objcen (car e)))
  185.                              (assoc 51 objlst)
  186.                              objlst
  187.                       )
  188.          )
  189.          (entmake objlst)
  190.        )
  191.        (entdel obj)
  192.       )
  193.       ((= objname "ELLIPSE")
  194.        ;;椭圆圆心
  195.        (setq objcen (cdr (assoc 10 objlst)))
  196.        ;;相对于中心的长轴矢量
  197.        (setq objaxis (cdr (assoc 11 objlst)))
  198.        ;;短轴与长轴的比例
  199.        (setq objratio (cdr (assoc 40 objlst)))
  200.        (repeat (- (length e) 2)
  201.          (setq e (cdr e))
  202.          (setq objlst (subst (cons 41 (pt->param (cadr e) objcen objaxis objratio))
  203.                              (assoc 41 objlst)
  204.                              objlst
  205.                       )
  206.          )
  207.          (setq objlst (subst (cons 42 (pt->param (car e) objcen objaxis objratio))
  208.                              (assoc 42 objlst)
  209.                              objlst
  210.                       )
  211.          )
  212.          (entmake objlst)
  213.        )
  214.        (entdel obj)
  215.       )
  216.     )
  217.   )
  218. )

  219. ;;计算耗时
  220. (defun xdl-getutime ()
  221.   (* 86400 (getvar "tdusrtimer"))
  222. )

  223. ;;求椭圆曲线参数
  224. (defun pt->param (pt cen axis ratio / ang param)
  225.   (setq ang (- (angle cen pt) (angle '(0. 0. 0.) axis)))
  226.   (cond        ((= (cos ang) 0.0)                ;防止分母cos为零出错
  227.          (if (> (sin ang) 0.0)
  228.            (setq param (* 0.5 PI))
  229.            (setq param (* 1.5 PI))
  230.          )
  231.         )
  232.         ((= (sin ang) 0.0)
  233.          (if (> (cos ang) 0.0)
  234.            (setq param 0.0)
  235.            (setq param PI)
  236.          )
  237.         )
  238.         (T
  239.          (setq param (atan (/ (sin ang) (* (cos ang) ratio))))
  240.          (if (< (cos ang) 0.0)
  241.            (setq param (+ pi param))
  242.          )
  243.         )
  244.   )
  245.   param
  246. )

  247. (princ
  248.   "\n**********批量交点打断程序,键入MB执行命令**********"
  249. )
  250. (princ)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2006-1-25 17:40:17 | 显示全部楼层
楼主的签名让我感动。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2006-2-7 08:41:31 | 显示全部楼层
几个建议:

1 求交点函数中用两个 Foreach 效率不高,建议用 两次 while

  1. (defun ssinters        (el / e1 el0 e2 ipts ipts)
  2.   (while el
  3.     (setq e1  (car el)
  4.           el0 (cdr el)
  5.     )
  6.     (while el0
  7.       (setq e2        (car el0)
  8.             el0        (cdr el0)
  9.       )
  10.       (if (and (setq ipts (vla-intersectwith e1 e2 0))
  11.                (setq ipts (vlax-variant-value ipts))
  12.                (> (vlax-safearray-get-u-bound ipts 1) 0)
  13.           )
  14.         ...
  15.       )
  16.     )
  17.   )
  18. )


2 DoEntmake 建议用 Entmod 代替 Entmake,以保持原实体的特性
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 24个

财富等级: 恭喜发财

 楼主| 发表于 2006-2-7 12:45:10 | 显示全部楼层
多谢eachy的建议。
1。用两个foreach属于比较偷懒的做法,代码相对简单,效率确实降低了。因为我需要得到的是与每个实体相关的交点列表,而非纯交点集,在最终生成的列表中是存在多个重复的交点的。
如下所示:
((#[VLA-OBJECT IAcadLine 09c38134] (764.958 570.843 0.0) (873.747 502.544 0.0) (989.975 429.573 0.0) (1076.41 375.306 0.0))
(#[VLA-OBJECT IAcadLine 09c48aa4] (1333.15 295.409 0.0) (1071.39 509.498 0.0) (971.052 591.563 0.0) (880.702 665.458 0.0))
(#[VLA-OBJECT IAcadLine 09c48fa4] (855.449 297.511 0.0) (989.975 429.573 0.0) (1071.39 509.498 0.0) (1217.41 652.842 0.0))
(#[VLA-OBJECT IAcadLine 09c48a24] (619.753 270.178 0.0) (873.747 502.544 0.0) (971.052 591.563 0.0) (1143.75 749.56 0.0)))
所以如果用while,则需要用subst不断更新这个列表,补充端点及交点。应该效率可以提高,我改改试试。
2。用entmod只能更新少数线条,比如100根横线条与100根竖线条相交,原实体200个,新实体20200,大多数还是需要用entmake生成的,所以不太清楚为何你建议我用entmod。
3。没有完全按照你的算法,排除了线条重叠的因素,我觉得删除重叠线条应通过另一个独立程序实现,可作为交点打断前的预处理程序。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2006-2-8 09:10:17 | 显示全部楼层
1 第一步指构造实体与交点表,不进行subst,全部构造完成后用 param 对交点在实体上排逆序,此时处理重复点(点沿实体排序在以前的帖子中有过讨论和代码)

2 对构造的实体和其交点表,用 entget 取得实体的 dxf  组码表,对 Line 而言可以用表替换 10 11 组码部分来 entmake 最后的实体用 entmod 或者 entmake,entmod 后的就不用 entdel 了。

3 同意你的观点,每个程序应该只干自己的事情。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-2-8 11:26:41 | 显示全部楼层
楼主的程序挺好的
有一点,如图,打断后的属性发生了变化
请问能否使打断后的颜色和层不要修改呢?谢谢
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 24个

财富等级: 恭喜发财

 楼主| 发表于 2006-2-8 12:46:45 | 显示全部楼层
To snoopychen  :
你的要求就是eachy提到的第二点。

根据eachy的建议修改了程序,首贴已更新。
当所选物体较多,而物体之间的交点不多时,效率显著提高。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2006-2-12 18:54:00 | 显示全部楼层
排序部分这样改改(未经测试)

  1. (defun xdl-pts-sortoncurve (el /)
  2.   (setq        el
  3.          (mapcar
  4.            '(lambda (lst)
  5.               (vl-sort (cdr lst)
  6.                        (function (lambda (p1 p2)
  7.                                    (< (vlax-curve-getParamAtPoint obj1 p1)
  8.                                       (vlax-curve-getParamAtPoint obj1 p2)
  9.                                    )
  10.                                  )
  11.                        )
  12.               )
  13.             )
  14.          )
  15.   )
  16.   ;;去除重复点
  17.   (mapcar '(lambda (lst / obj pts plst)
  18.              (setq obj (car lst)
  19.                    pts (cdr lst)
  20.              )
  21.              (foreach p        pts
  22.                (if plst
  23.                  (if (not (equal p (car plst) 0.00001))
  24.                    (setq plst (cons p plst))
  25.                  )
  26.                  (setq plst (cons p plst))
  27.                )
  28.              )
  29.              (cons obj plst)
  30.            )
  31.           el
  32.   )
  33. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 24个

财富等级: 恭喜发财

 楼主| 发表于 2006-2-12 21:49:16 | 显示全部楼层
eachy的意思我明白,这样可以不用新生成一个表。
我的考虑还是将obj1和pts分开,保留程序原有框架,因为
1。排序中vlax-curve-getParamAtPoint需要用到obj1
2。当某实体与任何物体都不相交时,不处理该实体,交点集pts是判断标准
3。当曲线不封闭时,需增加端点
诸多处理若将实体名和交点集统一在一起写函数太累,分开写程序可读性强一点,呵呵。
采用了你的去除重复点函数,多谢。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-2-12 23:41:17 | 显示全部楼层
和我的TlsBoundary类(vba在块内按点生成填充的)部分函数的思路是一致的,pline线是可以处理的,唯一的缺憾是无法对spline进行处理
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2006-4-2 12:29:31 | 显示全部楼层
lzh741206 ,为什么不能对spl处理?能说说么?





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

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

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

使用道具 举报

发表于 2007-1-24 00:46:25 | 显示全部楼层
不能对spline断开,这点不好啊,望尽快改进哦
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2009-12-3 21:14:53 | 显示全部楼层
使用时,发现程序对一些交叉的线打断时,会有bug,好像是(InterSort (ssinter elist))
生成的列表中,点的排列顺序有时候不对
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-1 12:17 , Processed in 0.536207 second(s), 61 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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