明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3767|回复: 17

剪切穿过圆的图元,如何判断剪切圆内还是圆外(已解决)

  [复制链接]
发表于 2011-10-31 10:44:00 | 显示全部楼层 |阅读模式
本帖最后由 xiaxiang 于 2011-10-31 16:51 编辑


如图,很简单,一根line穿过了circle。
我现在想执行剪切命令,通过偏移,栏选,剪切的永远是圆内的线。
如果我要剪圆外的线,应该如何操作?
当然,办法有很多。内外剪切的程序也有很多。只是想知道最直接,简练的一种,我不用判断图元与圆的关系,更不用去打断。我只要偏移,栏选。可能吗?
纠结了一上午?多谢施与援手。
2011.10.31 下午17:00
问题已解决,剪切边界的问题,低级错误!居然把边界搞错了。
用点集解决问题的方法请见12#。
剪切必须执行两次的bug,看来还是Autodesk的问题。
再次谢谢大家!

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2024-5-6 19:06:23 | 显示全部楼层
yjr111 发表于 2011-11-6 19:18
从收集的源码里找到的,剪切矩形框内的线,和你这放一起。。。不知道谁写的。。。

感谢分享,很好用的代码
发表于 2011-10-31 10:53:23 | 显示全部楼层
单依此例
线两端各点选一次即得
 楼主| 发表于 2011-10-31 11:28:01 | 显示全部楼层
举一个简单例子,我通过下面程序可以实现圆内剪切。我能通过修改实现圆外剪切吗?
原理是圆上做点,栏选剪切,比较简单。
欢迎指点。

  1. (defun c:ctrim ( / circ_pts lst ang inc tmp seg pt ent
  2.                    ctrim_err x f_pts svd_os svd_cmd svd_err)

  3. (defun ctrim_err (s)
  4.   (if(/= s "Function cancelled")
  5.   (princ(strcat "\n\n" s))     )
  6.   (setvar "cmdecho" svd_cmd)
  7.   (setvar "osmode" svd_os)
  8.   (setq *error* svd_err)
  9. )

  10. (defun circ_pts (enm)
  11.   (setq lst    (entget enm)
  12.         ang    (* pi 2)
  13.         inc    (/ ang 64)
  14.         tmp    '()
  15.         seg    65
  16.   )
  17.   (repeat seg
  18.    (setq pt (polar(cdr(assoc 10 lst))ang
  19.             (-(cdr(assoc 40 lst))0.01))
  20.         ang (+ inc ang)
  21.    )
  22.    (setq tmp(cons pt tmp))
  23.   )
  24.   tmp
  25. )

  26. (setq ent     (car(entsel "\nSelect circle: "))
  27.        svd_err *error*
  28.        *error* ctrim_err
  29.        svd_os  (getvar "osmode")
  30.        svd_cmd (getvar "cmdecho")
  31. )
  32. (setvar "cmdecho" 0)
  33. (setvar "osmode" 0)
  34. (if(and ent
  35.      (=(cdr(assoc 0(entget ent)))"CIRCLE")
  36.     )
  37.   (progn
  38.    (setq f_pts(circ_pts ent))
  39.    (command "trim" ent "" "f")   
  40.    (foreach x f_pts(command x))  
  41.    (command "" "")
  42.   )
  43. )
  44. (setvar "cmdecho" svd_cmd)
  45. (setvar "osmode" svd_os)
  46. (setq *error* svd_err)
  47. (princ)
  48. )

 楼主| 发表于 2011-10-31 11:30:04 | 显示全部楼层
Andyhon 发表于 2011-10-31 10:53
单依此例
线两端各点选一次即得

谢谢Andyhon ,但我只想要单选一次圆就能得到正确结果
发表于 2011-10-31 12:15:20 | 显示全部楼层
重新定义 circ_pts 即可
让点集砌成外切多边形
 楼主| 发表于 2011-10-31 14:33:52 | 显示全部楼层
本帖最后由 xiaxiang 于 2011-10-31 14:47 编辑
Andyhon 发表于 2011-10-31 12:15
重新定义 circ_pts 即可
让点集砌成外切多边形


没搞明白,这样剪切还是剪的外切多边形内部的线?
我用圆分别做内偏移和外偏移来剪切,得出的结果都是只剪切内部的线。
最奇怪的是曾经得出过正确的结果。不可能受系统变量的影响嘛。

发表于 2011-10-31 14:49:56 | 显示全部楼层
这种曲线事情直接找highflybir,问我浪费时间

点评

多谢提醒  发表于 2011-10-31 14:55
发表于 2011-10-31 14:56:49 | 显示全部楼层
...都是只剪切内部的线...
请上传更新后的代码+调试用的文件(*.Dwg)
发表于 2011-10-31 15:40:34 | 显示全部楼层
(polar cen  ang  (+ rad eps))
之类的可以让你直接取得圆内或者圆外的一点.
 楼主| 发表于 2011-10-31 16:09:08 | 显示全部楼层
Andyhon 发表于 2011-10-31 14:56
...都是只剪切内部的线...
请上传更新后的代码+调试用的文件(*.Dwg)

感谢Andyhon。犯了低级错误,用偏移后的圆作为边界,肯定会得到错误的结果。上传单向偏移的代码,可以剪切圆外部
  1. (defun c:ctrim ( / circ_pts lst ang inc tmp seg pt ent
  2.                    ctrim_err x f_pts svd_os svd_cmd svd_err)


  3. (defun ctrim_err (s)
  4.   (if(/= s "Function cancelled")
  5.   (princ(strcat "\n\n" s))     )
  6.   (setvar "cmdecho" svd_cmd)
  7.   (setvar "osmode" svd_os)
  8.   (setq *error* svd_err)
  9. )


  10. (defun circ_pts (enm)
  11.   (setq lst    (entget enm)
  12.         ang    (* pi 2)
  13.         inc    (/ ang 64)
  14.         tmp    '()
  15.         seg    65
  16.   )
  17.   (repeat seg
  18.    (setq pt (polar(cdr(assoc 10 lst))ang
  19.             (-(cdr(assoc 40 lst))0.01))
  20.         ang (+ inc ang)
  21.    )
  22.    (setq tmp(cons pt tmp))
  23.   )
  24.   tmp
  25. )

  26. (defun meoffset (obj dst / tmplst)
  27.   (if (not (vl-catch-all-error-p (setq tmplst (vl-catch-all-apply 'vlax-invoke (list obj 'offset dst)))))
  28.     tmplst
  29.   )
  30. )

  31. (setq ent     (car(entsel "\nSelect circle: "))
  32.        svd_err *error*
  33.        *error* ctrim_err
  34.        svd_os  (getvar "osmode")
  35.        svd_cmd (getvar "cmdecho")
  36. )
  37. (setvar "cmdecho" 0)
  38. (setvar "osmode" 0)
  39. (if(and ent
  40.      (=(cdr(assoc 0(entget ent)))"CIRCLE")
  41.     )
  42.   (progn
  43.    (meoffset (vlax-ename->vla-object ent) 0.1)   
  44.    (setq f_pts(circ_pts (entlast)))  
  45.    (repeat 2   
  46.    (command "trim" ent "" "f")   
  47.    (foreach x f_pts(command x))  
  48.    (command "" "")
  49.    )
  50.    (command "erase" (entlast) "")
  51.   )
  52. )
  53. (setvar "cmdecho" svd_cmd)
  54. (setvar "osmode" svd_os)
  55. (setq *error* svd_err)
  56. (princ)
  57. )

但是又有新的问题。为何此处非要执行两次?一次只能剪切一边,奇哉怪也。有兴趣的帮忙测试一下啊。谢谢
  1.    (repeat 2   
  2.    (command "trim" ent "" "f")   
  3.    (foreach x f_pts(command x))  
  4.    (command "" "")
  5.    )


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

本版积分规则

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

GMT+8, 2024-11-25 18:57 , Processed in 0.232202 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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