找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2513|回复: 27

[LISP函数]:请高手指点

[复制链接]
发表于 2003-5-1 16:13:33 | 显示全部楼层 |阅读模式

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

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

×
想请教一下,一条直线穿过若干个圆,能否用lisp实现一次将圆中的线依次全部剪断?我试了一下,但不太成功。线段被打断后原来的图元名称发生改变,导致无法识别已经定义过的线的名称,从而无法继续执行命令。但一个一个选择圆以后,就可以实现依次全部剪断。显然这样很不完美。
lisp程序能克服类似问题吗?如何解决这种问题,请高手赐教!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2003-5-1 16:55:25 | 显示全部楼层
先找出交点再通过交点做选择集
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2003-5-1 19:11:41 | 显示全部楼层

Re: [LISP函数]:请高手指点

最初由 ybyuan 发布
[B]想请教一下,一条直线穿过若干个圆,能否用lisp实现一次将圆中的线依次全部剪断?我试了一下,但不太成功。线段被打断后原来的图元名称发生改变,导致无法识别已经定义过的线的名称,从而无法继续执行命令。但一个一... [/B]

用lisp也可以,Break后的线起点部分还是原来的图元,后面的是新图元,所以你要从线的终点处往前break,也就是要对园按line的终点-》起点排序,然后就可以用Trim,边界选园,修剪实体用点对(圆心 <线实体>)这个线实体是不变的。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-5-1 19:19:39 | 显示全部楼层
你能求线-线交点就可以排序求新线。不过,好像还得先判断线与圆的关系,而且
可能会有大圆包容小圆的情况。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2003-5-1 20:18:49 | 显示全部楼层
应该要对点在这线的位置排序
(xdrx_SortPointOnCurve e ptn)   ;现在应该这么用(改了)

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

使用道具 举报

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

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2003-5-1 22:05:23 | 显示全部楼层
最初由 cy956 发布
[B]不判断你就break?第一点在圆内呢?在圆外呢? [/B]

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

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2003-5-1 22:42:38 | 显示全部楼层
最初由 cy956 发布
[B]不判断你就break?第一点在圆内呢?在圆外呢? [/B]


我是针对他的问题.
"线段被打断后原来的图元名称发生改变,导致无法识别已经定义过的线的名称"
判断他自己处理,他画的图自有他的规律.
一般是跟每个圆的两交点.如只一个,就要看顶点情况.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2003-5-1 22:55:59 | 显示全部楼层
单点打断,断开后肯定要生成一个实体,可以用(entlast)得到,判断下和原来的实体是否同名,就可以得到哪个是前一个,哪个是后一个。

如果要同时从一个线打断多个点,那么一个方法是,打断前把这些点按照这个线排序好,然后依次通过(entlast)就可以得到。

XDRX_API提供了现成的函数:

  1. <normalfont>
  2. 257. xdrx_curve_intersectbreak

  3. 功能:将选择集中的曲线在所有交点处break

  4. 调用格式:(xdrx_curve_intersectbreak < 选择集> [误差距离] [自身打断标记] [进度条间隔])

  5. 返回值:NIL

  6. 说明:参数
  7.         [误差距离]:整数或者实数,两个曲线顶点到另个曲线距离在误差内,算作相交
  8.         [自身打断标记]:T,对于复杂实体如POLYLINE,SPLINE等自身相交也打断,NIL不处理自身相交
  9.         [进度条间隔]:大于等于0的整数,为0,不显示进度条,大于0的值作为每处理这些实体后,进度条显示一次进度。
  10.         
  11.      不给这些参数,默认值是:误差100,自身打断T,无进度条0   
  12. </normalfont>
复制代码

  1. </normalfont>
  2. 256. xdrx_curve_getSplitCurves

  3. 功能:给一些点或者参数值,break曲线

  4. 调用格式:(xdrx_curve_getSplitCurves < 曲线实体名 > < p1>...< pn>)
  5.          (xdrx_curve_getSplitCurves <曲线实体名> < 参数1>...< 参数n>)

  6. </normalfont>
复制代码


点表按照已知线或者(P1 P2)组成的线排序的函数是:

  1. <normalfont>
  2. 153. xdrx_SortPointOnCurve

  3. 功能:基于实体的点的排序函数,就是有一系列点是在曲线实体上,基于这个曲线实体,从开始点
  4.      到结束点排序这些实体上的点。结果是这些点依据实体的开始点开始排升序。
  5.      
  6. 调用格式:(xdrx_SortPointOnCurve <曲线实体名> (<p1>....<pn>))
  7.           (xdrx_SortPointOnCurve (p1 p2) (<p1>....<pn>))
  8.          
  9. 返回值:以曲线实体的开始参数为基点,排升序后的表。

  10. 例子: 该函数在求一个曲线和其他所有曲线的交点的时候,很常用。
  11.       如:求一个已经的ARC和一些曲线实体的交点,然后为了下面的操作需要讲这些得到的交点
  12.          排序,以前的做法是得到交点后,还需要根据某个特征,如求这些点到一个图形最小点
  13.          的距离等等作为依据,排序。(这种方法的缺点就是若第一个曲线参数不是LINE,而是ARC
  14.          等曲线,那么就非常不容易排序。现在有这个函数,问题就很好解决了。
  15.          
  16.          (setq e (car (xdrx_entsel "\n请选取一个曲线实体:" '((0 . "*line,arc,ellipse")))));;得到一个曲线
  17.          (setq ptl (xdrx_getsamplept e)) ;;得到这个曲线的模拟顶点表
  18.          (setq ss (ssget "f" ptl '((0 . "*line,arc,ellipse")))) ;;得到所有和这个曲线相交的曲线实体到选择集ss
  19.          (setq ptl (xdrx_getinters e ss)) ;;得到曲线E和选择集中所有曲线的实际交点,不延伸。
  20.          (setq p (cons e ptl)) ;;构造基于实体排序的函数xdrx_SortPointOnCurve的参数表
  21.          (setq ptl (apply 'xdrx_sortpointoncurve p)) ;;得到了排序后的点。
  22.          
  23.       这些功能若不用XDRX_API,只用LISP,要用几十倍的代码量才能完成。
  24.       
  25.       这些代码在求如建筑上轴网交点等等操作,极大的简化了代码量,速度还很快。
  26.       
  27.       可以求任意实体的交点和排序。

  28. </normalfont>


所以,你的到了所有的交点后(setq pts (p1 p2 ...pn)) 用下面的方法:

  1. <normalfont>
  2. 下面的代码把你选的LINE和相交的圆,在交点处打断LINE

  3. (if (and
  4.       (setq e1 (car (xdrx_entsel "\n拾取LINE<退出>:" '((0 . "line")))))
  5.       (setq e2 (car (xdrx_entsel "\n拾取CIRCLE<退出>:" '((0 . "circle")))))
  6.       (setq intl (xdrx_getInters e1 e2)) ;;获得LINE和CIRCLE的交点表
  7.     )
  8.   (progn
  9.     (setq intl (xdrx_sortPointOnCurve e1 intl)) ;;按照LINE排序点表
  10.     (xdrx_curve_getSplitCurves (cons e1 intl))  ;;从所有点打断LINE
  11.   )
  12. )


  13. </normalfont>




就完成你要的在所有点打断这个操作了。


如果你连CIRCLE也想一起打断,就更方便了,选择两个实体后:

  1. <normalfont>
  2. (setq ss (ssadd))
  3. (ssadd e1 ss)
  4. (ssadd e2 ss)
  5. (xdrx_curve_intersectbreak ss)
  6. </normalfont>


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

使用道具 举报

发表于 2003-5-1 23:56:49 | 显示全部楼层
我觉得没有必要那么复杂,可以参考陈伯雄的书《Visual LISP程序设计--技巧与范例》中说过的一种不停的Extend已得到直线和园交点的方法,而且这种方法得到的点自身就是按照顺序的。把所有的点顺序纪录,最后重新一段一段生成就行了
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2003-5-2 04:35:31 | 显示全部楼层
或许还可以更简单-求出各圆心到直线的垂足,然后trim...
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2003-5-2 10:06:39 | 显示全部楼层
感谢版主晓东,感谢楼上的每一位高手!我会按找你们的思路和建议去尝试,等有结果我会与大家分享。
--------------------------------------------------------
在朋友们的提示下,我用trim很快解决了我的问题。虽然还不完善,但可以满足要求了。不完善之处主要是在用trim命令时,我的第二选项用了“圆心坐标(cen)“。如果线距离圆心很远的情况下,将不执行剪切。不知哪位高手能帮忙完善(还有斜线相交等情况)。
还想请教楼上的eachy,怎么样才能对圆按line的终点-》起点进行排序?另外能举例说明如何用“点对“吗?谢谢!~

  1. (defun C:tt ()
  2.   (setvar "cmdecho" 0)
  3.   (prompt "\n select the circle:")
  4.   (setq cir (ssget))
  5.   (setq index 0)
  6.   (setq n (sslength cir))
  7.   (repeat n
  8.     (setq name (ssname cir index))
  9.     (setq a1 (entget name))
  10.     (setq index (1+ index))
  11.     (progn
  12.       (setq cen (cdr (assoc 10 a1)))
  13.       (command "trim" name "" cen "")
  14.     )
  15.   )
  16.   (princ)
  17. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2003-5-2 12:00:22 | 显示全部楼层

  1. (defun c:br( / circle j len line p1 p2 pt ptn ss)
  2. (if(and(setq line(car(entsel)))
  3.         (setq ss(ssget '((0 . "CIRCLE"))))  )
  4. (progn
  5.   (setq ptn(xdrx_getinters line ss  1))
  6.   (setq ptn(reverse(xdrx_SortPointOnCurve line ptn)) j 0 len(length ptn))
  7.   (while(< j len)
  8.   (setq p1(nth j ptn)p2(nth(1+ j)ptn))
  9.   (command"break"(list line p1) p2)
  10.   (setq j(+ 2 j))
  11.   )))(princ)
  12. )
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2003-5-2 14:35:57 | 显示全部楼层

(再次更新)

最初由 ybyuan 发布
[B]感谢版主晓东,感谢楼上的每一位高手!我会按找你们的思路和建议去尝试,等有结果我会与大家分享。
--------------------------------------------------------
在朋友们的提示下,我用trim很快解决了我的问题。虽... [/B]

这样改下试试,原理就是和手工修剪一样。

  1. (defun C:tt (/ cir ln index name cen n)
  2.   (setvar "cmdecho" 0)
  3.   (if (progn
  4.         (prompt "\n select the circle:")
  5.         (setq cir (ssget '((0 . "circle"))))
  6.         (setq ln (car (entsel "\nselect line: ")))
  7.       )
  8.     (progn
  9.       (setq index 0
  10.             n 0
  11.       )
  12.       (repeat (sslength cir)
  13.         (setq name (ssname cir index))
  14.         (setq index (1+ index))
  15.         (setq cen (cdr (assoc 10 (entget name))))
  16.         (command ".trim" name "" (list ln cen) "")
  17.         (if entlst
  18.           (setq entlst (list (entlast)))
  19.           (setq entlst (append (list (entlast)) entlst))
  20.         )
  21.       )
  22.       ;;处理嵌套圆
  23.       (repeat (sslength cir)
  24.         (setq name (ssname cir n))
  25.         (setq n (1+ n))
  26.         (setq cen (cdr (assoc 10 (entget name))))
  27.         (foreach e entlst
  28.           (command ".trim" name "" (list e cen) "")
  29.         )
  30.       )
  31.     )
  32.   )
  33.   (princ)
  34. )

圆心点依曲线排序可以这样:将点向线上作对应的垂点,以垂点为索引按X或Y排序即可,对于相等的可以再按垂距排序。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-27 00:11 , Processed in 0.204671 second(s), 61 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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