明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1333|回复: 8

[提问] 求一段代码,框选几组同心圆,只留最小一个,其他删除

[复制链接]
发表于 2019-12-4 00:02:59 | 显示全部楼层 |阅读模式
3明经币
本帖最后由 wgij007 于 2019-12-4 00:10 编辑


如图,框选几组同心圆,第组只留最小一个,其他删除
附件: 您需要 登录 才可以下载或查看,没有账号?注册

最佳答案

查看完整内容

(defun c:tt (/ center center-lst dxf lst name radius ss temp) (if (setq ss (ssget '((0 . "CIRCLE")))) (progn (while (setq name (ssname ss 0)) (setq dxf (entget name)) (setq Center (cdr (assoc 10 dxf))) (setq radius (cdr (assoc 40 dxf))) (setq lst (append lst (list (list Center radius name)))) (ssdel name ss) ) (foreach x lst (if (not (member (car x) C ...
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2019-12-4 00:03:00 | 显示全部楼层
(defun c:tt (/ center center-lst dxf lst name radius ss temp)
        (if (setq ss (ssget '((0 . "CIRCLE"))))
                (progn
                        (while (setq name (ssname ss 0))
                                (setq dxf (entget name))
                                (setq Center (cdr (assoc 10 dxf)))
                                (setq radius (cdr (assoc 40 dxf)))
                                (setq lst (append lst (list (list Center radius name))))
                                (ssdel name ss)
                        )
                        (foreach x lst
                                (if (not (member (car x) Center-lst))
                                        (setq Center-lst (append Center-lst (list (car x))))
                                )
                        )
                        (foreach x Center-lst
                                (setq temp nil)
                                (foreach xx lst
                                        (if (equal (car xx) x)
                                                (setq temp (append temp (list (list (cadr xx) (caddr xx)))))
                                        )
                                )
                                (setq temp (cdr (vl-sort temp '(lambda (a b)
                                                                                                                                                                 (< (car a) (car b))
                                                                                                                                                         )
                                                                                                )
                                                                         )
                                )
                                (foreach x temp
                                        (entdel (cadr x))
                                )
                        )
                )
        )
)
回复

使用道具 举报

发表于 2019-12-4 05:00:19 | 显示全部楼层
如果能保证圆心相同,那很好处理,否则需要设置容错值.


(defun c:ttt ( / fuzz ss lst_en y  lst_tmp y_10 lst_en wyl:ss2ptlistatlst wyl:ss2ptlist)
        (setq fuzz 20);设置容错值
                ;;选择集转为dxf列表
                ;;说明:传入选择集,将对应的组码返回
                ;;参数:ss:选择集
                ;;参数:dxf:组码,例如10代表插入点,0代表对象类型,2代表对象名,8代表图层,-1是图元名
                ;;返回:列表
                (defun wyl:ss2ptlist ( ss dxf / n i elist )
                        ;(defun ss2ptlist ( ss / )
                        (setq n (if (= (type ss) 'Pickset) (sslength ss) 0)
                                elist '()
                        )
                        (repeat n
                                (setq elist (cons  (cdr (assoc dxf  (entget (ssname ss (setq n (1- n))))))  elist))
                        )
                )
        ;|
        选择集转为dxf列表
        说明:传入选择集或图元列表,将对应的组码返回
        参数:ss:选择集
        参数:dxf:组码组成的列表,例如10代表插入点,0代表对象类型,2代表对象名,8代表图层,-1是图元名
        可以仅为一个int,可用""代替-1即图元名.
        返回:列表,每个子项的顺序和参数相同
        (wyl:ss2ptlistatlst ss1 "") 返回(图元名 图元名)
        (wyl:ss2ptlistatlst ss1 -1) 返回(图元名 图元名)
        (wyl:ss2ptlistatlst ss1 8) 返回(图层 图层)
        (wyl:ss2ptlistatlst ss1 (-1 8)) 返回((图元名 图层)(图元名 图层))
        (wyl:ss2ptlistatlst ss1 ("" 8)) 返回((图元名 图层)(图元名 图层))
        新增支持传入图元列表
        |;
        (defun wyl:ss2ptlistatlst ( ss dxflst / n elist falg elistr )
                (if (not (listp dxflst));如果不是列表,转换成列表,统一一下,其实这里统一了也没什么意义
                        (setq dxflst (list dxflst)))
                (setq falg (length dxflst));设置一个标志,方便下面确定返回值
                (setq dxflst(subst -1 "" dxflst ));把""替换成-1
                (if (= (type ss) 'Pickset) ;如果传入的参数为选择集
                        (setq ss (wyl:ss2ptlist ss -1));把选择集转换成图元列表
                )
                ;(setq n (if (= (type ss) 'Pickset) (sslength ss) 0))
                (foreach x ss
                        (setq elist nil);每次循环要先把这里清0
                        (cond
                                ((= 1 falg)
                                        (setq elist (cdr (assoc (car dxflst)  (entget x))))
                                )
                                (t
                                        (foreach y dxflst
                                                (setq elist (append  elist (list (cdr (assoc y  (entget x))))  ))
                                        )
                                )
                        )
                        (setq elistr (append (list elist) elistr))
                )
        )
        ;main
        (setq ss (ssget '((0 . "CIRCLE"))))       
        (setq lst_en (wyl:ss2ptlistatlst ss (list -1 10 40)));返回值为((图元名 坐标 半径) (图元名 坐标 半径))
        (while (> (length lst_en) 1);当只剩一个图元的时候,退出循环
                (setq y (nth 0 lst_en )
                        lst_tmp (list y);临时列表
                        y_10 (cadr y);参照图元的坐标
                        lst_en (vl-remove y lst_en)
                );获取首个图元,并将其从列表中删除
                (setq x (nth 0 lst_en))
                (foreach x lst_en;根据圆心分组处理
                        (if (<= (distance y_10 (cadr x)) fuzz);如果圆心距离不大于容错值
                                (setq lst_tmp (append lst_tmp (list x))
                                        lst_en (vl-remove x lst_en)
                                );将x从图元列表中删除,并加入到临时列表中
                        ));endforeach
                (if (> (length lst_tmp) 1);如果有与第一个图元同心的圆
                        (progn
                                (setq lst_tmp (cdr (vl-sort lst_tmp '(lambda(x y) (< (caddr x) (caddr y))))));根据直径排序,最小的在最前被删除
                                (foreach x lst_tmp
                                        (entdel (car x));删除其余的图元
                                )
                        )
                );endif
        );endwhile
)
(princ)
回复

使用道具 举报

发表于 2019-12-4 09:38:43 | 显示全部楼层
pycad
linq例程

  1. @command()
  2. def linqtest(doc):
  3.     import clr, System
  4.     clr.ImportExtensions(System.Linq)
  5.     ed = doc.Editor
  6.     res = ed.SelectAll(conv.BuildFilter((0, 'circle')))
  7.     if res.Status != aced.PromptStatus.OK:
  8.         return
  9.     ss = res.Value
  10.     with dbtrans(doc) as tr:
  11.         cirs = ss.Cast[aced.SelectedObject]().Select(lambda o: tr.getobject(o.ObjectId))
  12.         q = cirs.GroupBy(lambda c: c.Center).SelectMany(lambda cs: cs.OrderBy(lambda c: c.Radius).Skip(1))
  13.         print(q.Count())
  14.         for cir in q:
  15.             with upopen(cir):
  16.                 cir.Erase()
复制代码
回复

使用道具 举报

 楼主| 发表于 2019-12-4 11:53:10 | 显示全部楼层
taoyi0727 发表于 2019-12-4 11:14
(defun c:tt (/ center center-lst dxf lst name radius ss temp)
        (if (setq ss (ssget '((0 . "CIRCLE") ...

非常感谢!
回复

使用道具 举报

发表于 2019-12-4 23:42:44 | 显示全部楼层
  1. (defun c:tt () ; tt(框选几组同心圆,只留最小的一个)
  2.   (if (setq ss (ssget '((0 . "CIRCLE")))
  3.             lst (xyp-Ss2List ss)
  4.       )
  5.     (while lst
  6.       (setq pt (xyp-DXF 10 (car lst))
  7.             lst1 (vl-remove-if-not '(lambda (x) (equal (xyp-DXF 10 x) pt)) lst)
  8.             lst1 (vl-sort lst1 '(lambda (x y) (< (xyp-DXF 40 x) (xyp-DXF 40 y))))
  9.             lst (vl-remove-if '(lambda (x) (equal (xyp-DXF 10 x) pt)) lst)
  10.       )
  11.       (xyp-erase (cdr lst1))
  12.     )
  13.   )
  14.   (princ)
  15. )
回复

使用道具 举报

发表于 2020-3-13 11:45:17 | 显示全部楼层
wyl219 发表于 2019-12-4 05:00
如果能保证圆心相同,那很好处理,否则需要设置容错值.

加入容错值是非常正确的思路,但该程序执行时把其他完全同心的圆也删除了结果不是如题目所要的框选圆,删除最大只留最小。把不该删的也删除了。
回复

使用道具 举报

发表于 2022-12-8 16:08:30 | 显示全部楼层
taoyi0727 发表于 2019-12-4 00:03
(defun c:tt (/ center center-lst dxf lst name radius ss temp)
        (if (setq ss (ssget '((0 . "CIRCLE") ...

应该来个选择,比如删除大的,还是小的,更好
回复

使用道具 举报

发表于 2022-12-8 16:12:06 | 显示全部楼层
wyl219 发表于 2019-12-4 05:00
如果能保证圆心相同,那很好处理,否则需要设置容错值.

应该来个选择,比如删除大的,还是小的,更好
回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-16 04:15 , Processed in 0.182031 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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