明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2072|回复: 10

[已解答] 如何清除园内圆

[复制链接]
发表于 2013-12-6 22:40 | 显示全部楼层 |阅读模式
(defun c:tt5(/ getcirpts ssgetcir s en ss dxf ptincir-p lineincir-p SS->List)
  ;;;计算园的分割点 en 园的图元名 n 园的分割段数
  (defun getcirpts (en n / i d pl)
    (setq i 0 d (/ pi n 0.5))
    (repeat n
      (setq pl (cons (vlax-curve-getpointatparam en i) pl)
            i (+ i d)
            )
      )
    (reverse pl)
    )
  ;;;参数 cir 园的图元名 filter 过滤表 n 园的分割段数
  (defun ssgetcir (cir filter n / ss)
    (if filter
      (setq ss (ssget "cp" (getcirpts cir n) filter))
      (setq ss (ssget "cp" (getcirpts cir n)))
      )
    (ssdel cir ss)
    (if (> (sslength ss) 0)
      ss
      )
    )
  (defun dxf (ent i)
    (cond ((= (type ent) 'ename)
     (cdr (assoc i (entget ent)))
      )
   ((= (type ent) 'list)
    (cdr (assoc i ent))
    )
    ) ;_ if
  )
  ;;;判断点是否在园内
  (defun ptincir-p (cir pt / r cp d)
    (setq r (dxf cir 40)
   cp (dxf cir 10)
   )
    (or (< (setq d (distance cp pt)) r) (equal d r 0.0001))
    )
  ;;;判断直线是否在园内
  (defun lineincir-p (line cir)
    (and (ptincir-p cir (dxf line 10))
  (ptincir-p cir (dxf line 11))
  )
    )
  ;;;选择集->列表
  (defun SS->List (ss / i s)
    (if ss
      (repeat (setq i (sslength ss))
(setq s (cons (ssname ss (setq i (1- i))) s))
      )
    )
  )
  ;;;选择的园要在图形可见范围内
  (setq s (ssget '((0 . "circle"))))
  (if s
    (progn
      (setq s (ss->list s))
      (foreach cir s
      (if (setq ss (ssgetcir cir '((0 . "line")) 20))
        (progn
   (setq ss (ss->list ss))
   (foreach line ss
     (if (lineincir-p line cir) (entdel line))
     )
   )
        )
)
      )
    )
(princ)
  )


怎么清除园内圆,帮改改,谢谢了
发表于 2013-12-6 23:10 | 显示全部楼层
圆内圆指小圆完全在大圆内,与大圆无交点的那种吗?
发表于 2013-12-7 08:07 | 显示全部楼层
(setq ss (ssgetcir cir '((0 . "line")) 20))
改成
(setq ss (ssgetcir cir '((0 . "CIRCLE")) 40))
试试
 楼主| 发表于 2013-12-7 10:11 | 显示全部楼层
革天明 发表于 2013-12-6 23:10
圆内圆指小圆完全在大圆内,与大圆无交点的那种吗?

是的,圆内圆指小圆完全在大圆内,与大圆无交点的那种。
 楼主| 发表于 2013-12-7 10:41 | 显示全部楼层
ZZXXQQ 发表于 2013-12-7 08:07
(setq ss (ssgetcir cir '((0 . "line")) 20))
改成
(setq ss (ssgetcir cir '((0 . "CIRCLE")) 40))

得先判断园内园 再删除吧?
发表于 2013-12-7 12:01 | 显示全部楼层
其实楼主的一个问题就是如何准确判断小圆是否在大圆内,确实,圆不象多线段可以SSGET "w"方式去得到它里边的东东,当然用多线段去拟合它也不是不可以,但始终面临一个拟合度要取多大的问题,而实际上不管你拟合度多大,总可以画出在圆内而在拟合线外的东东,所以不能这样干,得从数学的方面考虑:
1.假设大圆O1圆心p1半径r1,小圆O2圆心p2半径r2,如果(<(+(distance p1 p2)r2))r1)那么O2在O1内......
2. ssget "F"(list p1 p2)如果只有一个圆那么必定有一个圆的圆心在另一个圆内.....
发表于 2013-12-7 21:20 | 显示全部楼层
llsheng_73 发表于 2013-12-7 12:01
其实楼主的一个问题就是如何准确判断小圆是否在大圆内,确实,圆不象多线段可以SSGET "w"方式去得到它里边的 ...

支持这个观点,思路对了才能事半功倍,圆心和半径都是固定数,筛选出符合要求的圆删除,这样才合理,有效率。
发表于 2013-12-7 22:04 | 显示全部楼层
代码如下,结果如图片所示,右侧为运行后的结果。

(defun c:ny ()
  ;;----通用函数-----
  ;;carrot1983  http://bbs.mjtd.com/forum.php?mod=viewthread&tid=64502
  ;;选择集->图元名表
  (defun ss->elst (ss / elst)
    (setq i 0)
    (repeat (sslength ss)
      (setq elst (cons (ssname ss i) elst)
            i         (1+ i)
      )
    )
    (reverse elst)
  )
  ;;自定义函数,用于判断两个圆是否相交lst1表示大圆的数组(list 图元名 圆心 半径)
  ;;圆心距与小圆半径之和小于大圆半径,则小圆肯定在大圆内
  (defun c-c (lst1 lst2 / flag)
    (if        (< (+ (distance (cadr lst1) (cadr lst2)) (caddr lst2))
           (caddr lst1)
        )
      (setq flag T)
    )
    flag
  )
  (prompt "\n请选择要清理的圆")
  (setq ss (ssget '((0 . "CIRCLE"))))
  (setq sslst (ss->elst ss))
  (setq        sslst
         (mapcar '(lambda (x / data)
                    (setq data (entget x))
                    (list x (cdr (assoc 10 data)) (cdr (assoc 40 data)))
                  )
                 sslst
         )
  )
  (setq        sslst (vl-sort sslst
                       '(lambda        (e1 e2)
                          (> (caddr e1) (caddr e2))
                        )
              )
  )
  (setq        i 0
        j 0
        dellst '()
  )
  (repeat (length sslst)
    (setq j i)
    (repeat (- (length sslst) i 1)
      (if (c-c (nth i sslst) (nth (1+ j) sslst))
        (setq dellst (cons (nth (1+ j) sslst) dellst))
      )
      (setq j (1+ j))
    )
    (setq i (1+ i))
  )

  ;;图元表转为选择集  http://bbs.mjtd.com/forum.php?mod=viewthread&tid=84780  作者 redcat
  ;;格式:(ents->ss ents ss)
  ;;如果选择集ss/=nil将ents表中的图元加入到ss中,并返回ss
  ;;如果 ss=nil,新建一个选择集并返回.
  ;;(ents->ss (sset->list (ssget) nil) nil)
  (defun ents->ss (ents ss / ename)
    (if        (= ss nil)
      (setq ss (ssadd))
    )
    (mapcar '(lambda (ename)
               (setq ss (ssadd ename ss))
             )
            ents
    )
    ss
  )
  (setq        dellst (mapcar '(lambda        (x)
                          (car x)
                        )
                       dellst
               )
  )
  (setq ss1 nil)
  (command "erase" (ents->ss dellst ss1) "")
)

本帖子中包含更多资源

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

x
发表于 2013-12-7 22:11 | 显示全部楼层
xskfq 发表于 2013-12-7 10:11
是的,圆内圆指小圆完全在大圆内,与大圆无交点的那种。

问题已经解决了,若有问题再反馈
 楼主| 发表于 2013-12-9 22:29 | 显示全部楼层
革天明 发表于 2013-12-7 22:11
问题已经解决了,若有问题再反馈

问题完美解决。厉害。。十分感谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-19 23:59 , Processed in 0.617809 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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