明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: zzl9105

多点打断问题,及想问下list的用法

  [复制链接]
发表于 2011-10-19 18:37:54 | 显示全部楼层
zzl9105 发表于 2011-10-19 17:07
回复vormittag 的点评
打断的思路有很多的,你说的这点,早有想到,呵呵,也很好操作,不存在排序问题,但 ...

(foreach .....)语句虽然写在一行,并不表示计算机是同时(数学上精确的同一时间点)在n个点把多义线打断,计算机的操作也是有先后顺序的,你打断操作的核心在 (command "_.break" (list EN PT) "f" "non" PT "non" PT)这一句,这就是一个单点打断,这一句伴随而来的就是新生成图元。就算你排序排准确,(foreach ...)操作以后你就能把小于300长的新图元找出来么?

其实我没回避一线多点打断的可实现性。只不过我的想法是通过对交点循环来实现的。你完全可以用一个长度为1的选择集。我回避的是“一次”,因为我要用的打断操作核心和你用的是一样的,这个操作就不可能做到“一次”。而且只要能打断,增加图元是必然的,即使你能同时(数学上精确的同时)打断,多出来的图元可能是同一个句柄同一个图元名么?

如果要把打断线长度小于300的集中到一个选择集里,我的思路也很容易办到,每次打断后新生成的图元都加入到原选择集里,最后判断一下选择集里所有图元哪些长度小于300,挑出来就是了。

还有:我不认为求交点集的时候有判断及处理点是否重复的必要。重复了多做一次也没什么了不起,就操作内容来看不会产生坏影响。如果对程序处理时间有近乎洁癖的要求,那就求点集前处理一下,但这是求交点集的工作,而且(foreach .....) 里不一样也有重复点问题么?
发表于 2011-10-20 06:52:26 | 显示全部楼层
9楼说的非常的对,要使用entlast函数,指定打断后的物体,让它继续执行,你的程序肯定是有问题的
 楼主| 发表于 2011-10-20 09:44:11 | 显示全部楼层
vormittag 发表于 2011-10-19 18:37
(foreach .....)语句虽然写在一行,并不表示计算机是同时(数学上精确的同一时间点)在n个点把多义线打断 ...

那就不知道你在9楼时说的什么意思了?算法是没有问题的,你自己好好体会吧。
反正我的程序已经实现打断了。
至于我说的想再增加判断300长的功能,加几句就能实现了,呵呵
顺便说一下,你既然有你的思路,可否把你的晒出来,大家交流一下呀?

点评

目前的代码,依然存在bug,可能这不是一个好的办法。再往下走可能会是死胡同!  发表于 2011-10-20 10:41
发表于 2011-10-20 13:27:56 | 显示全部楼层
zzl9105 发表于 2011-10-20 09:44
那就不知道你在9楼时说的什么意思了?算法是没有问题的,你自己好好体会吧。
反正我的程序已经实现打断了 ...

仔细看了看,我在9楼的帖子意思表达得很清楚啊。如果说一定有什么不准确的地方,就是我少了一句状语:“在未对点表中的点进行特定排序的条件下”。可这是论坛发贴子,不是学报投论文,不需要添加这么一句吧?况且楼顶的帖子并没有说明ptlist已经经过特定的排序了。我在这个前提下作出“算法有问题”的结论,有什么问题?
至于我的思路的实现代码,贴在下面了
  1. (defun c:dd( / ss ss1 ii jj pt5 pt3 pt4 pl ename1 ell1 type echo os)
  2.         (setq ss (ssget '((0 . "*LINE,ARC")))
  3.                   pl   (getinterptlist ss)
  4.                   ii   0
  5.                   os   (getvar "OSMODE")
  6.                   echo (getvar "CMDECHO")
  7.         );setq
  8.         (setvar "OSMODE" 0)
  9.         (setvar "CMDECHO" 0)
  10.     (repeat (length pl)
  11.                 (setq pt5 (nth ii pl)
  12.                       ii  (1+ ii)
  13.                           pt3 (polar (trans pt5 0 1) (* pi 0.75) 0.0001)
  14.                           pt4 (polar (trans pt5 0 1) (* pi 1.75) 0.0001)
  15.                           ss1 (ssget "c" pt3 pt4)
  16.                           jj  0
  17.                           pt5 (trans pt5 0 1)
  18.                 );setq
  19.                 (repeat (sslength ss1)
  20.                         (setq ename1 (ssname ss1 jj)
  21.                                   ell1   (entget ename1)
  22.                                   jj      (1+ jj)
  23.                                   type   (cdr (assoc 0 ell1))
  24.                         );setq
  25.                         (if (and (ssmemb ename1 ss) (member type (list "LINE" "LWPOLYLINE" "SPLINE" "ARC")))
  26.                                 (progn
  27.                                         (vl-cmdf "_break" ename1 pt5 pt5)
  28.                                         (setq ss (ssadd (entlast) ss))
  29.                                 );progn
  30.                         );if
  31.                 );repeat
  32.         );repeat
  33.     (setvar "OSMODE" os)
  34.         (setvar "CMDECHO" echo)
  35.     (princ)       
  36. )
  37. (defun getinterptlist( ss / i j datalist ptlist pt e1 e2 k)
  38.     (setq i 0 ptlist '())
  39.         (repeat (sslength ss)
  40.             (setq e1 (vlax-ename->vla-object (ssname ss i))
  41.               i  (1+ i)
  42.                           j  i
  43.         );setq
  44.                 (repeat (- (sslength ss) i)
  45.                 (setq e2       (vlax-ename->vla-object (ssname ss j))
  46.                                   j        (1+ j)
  47.                                   datalist (vlax-invoke e1 'intersectwith e2 0)
  48.                         );setq
  49.                         (if datalist
  50.                             (progn
  51.                                     (setq k 0)
  52.                                 (while (nth k datalist)
  53.                                                 (setq pt     (list (nth k datalist) (nth (1+ k) datalist))
  54.                                                       ptlist (append ptlist (list pt))
  55.                                               k      (+ 3 k)
  56.                                                 );setq
  57.                                 );while
  58.                                 );progn
  59.                         );if
  60.                 );repeat
  61.         );repeat
  62.         ptlist
  63. )
另:算法不是我说有问题就有问题,更不是你说没问题就没问题的。我也不会奉劝别人“好好体会”。
发表于 2011-10-20 14:26:07 | 显示全部楼层
vormittag 发表于 2011-10-20 13:27
仔细看了看,我在9楼的帖子意思表达得很清楚啊。如果说一定有什么不准确的地方,就是我少了一句状语:“在 ...

测试过LINE,ARC,LWPOLYLINE,SPLINE都能打断,没发现bug
 楼主| 发表于 2011-10-20 16:14:25 | 显示全部楼层
语有唐突,请vormittag 别生气啊,本无恶意。
你上传的那个,和网友消遥网发我的一样,难道你就是他?
bug应该是排序出了问题,斜向的线,可以全部打断,横竖正交的,却不能?
感觉它应该可以排的呀?16楼的高手Andyhon ,可否现身指点下呀。
旋转一个角度,确实能全部打断,可是为啥呀,即使水平线,用y坐标排序,
失效后,不是还有一个x坐标吗?应该也能排的呀?
难道说先用x排好后,再用y排,反而能把它打乱了不成?(对于水平线)
有网友建议,将x,y,z整合到一个vl-sort中用cond分情况排序,可惜没写好
还有就是用距离排序,也写了一个,老是说缺参数,基础不扎实啊

点评

亲测旋转之后也不能全部打断  发表于 2011-10-20 17:55
我说话有时阴阳怪气的,但是都不表示我会生气,如果生气就什么话都不说了 :)。  发表于 2011-10-20 16:27
发表于 2011-10-20 16:47:09 | 显示全部楼层
zzl9105 发表于 2011-10-20 16:14
语有唐突,请vormittag 别生气啊,本无恶意。
你上传的那个,和网友消遥网发我的一样,难道你就是他?
bu ...

1、我不是逍遥网。
2、这段代码完全是我自己写的。
3、我在网上也和别人交流过这个问题,他和你的思路一样,后来我把这段代码给了他。我不知道他是不是逍遥网。其实这些都不重要,我现在写的东西本来也想做成开源的freeware.
4、之前一直不想贴出来是因为我的同事在应用时出过错(也是有没打断的),因为我前前后后改了很多次,我也不确定他用的是那一版的,也不确定现在的版本是不是不出错了,想彻底查一下却总没时间。
5、排序的问题我再看看想想再说。
发表于 2011-10-20 17:51:57 | 显示全部楼层
排序还是不要考虑了。
下载了你的测试文件,作一点小改动,把一条直线的方向换了(起终点互换),用先排序点再打断的办法就不行了。打断图元的时候,原图元名的实体是线的起点到打断点的部分,打断点到终点的部分是新图元。如果foreach 的语句要得到想要的结果,ptlist的点要按照终点沿曲线到起点的顺序排列。这意味着,对于每一个图元,都要把ptlist点集重新排序,工作量太可怕了。
发表于 2011-10-20 19:12:44 | 显示全部楼层
vormittag兄说的很中肯,而且思维明显周密很多,再说也是技术交流,楼主本来就是把源码贴出来让大家讨论的吗?开源的东西,本就是越多的人参与,程序越健壮,别人有好的意见,好的思路,我们是要吸收的。这样也利于自己提高,没有人敢说他做的所有的程序没有一点补丁,如果有高人看到自己程序的问题,我们要感谢人家,自己也会进步呀。
发表于 2011-10-20 20:15:29 | 显示全部楼层
本帖最后由 Gu_xl 于 2011-10-20 20:16 编辑

    关于曲线选择集的交点打断,采用break方法是最容易想到的,编程也易于实现,但是用command方法打断这绝不是一个好方法,当选择集曲线数量有限时,效率也就无所谓,但是当选择集曲线数量很多时,效率就是我们不得不考虑的事情了,command方法是我们首先要排除使用的方法!
  我的方法是先计算出每个曲线上得交点,逐个曲线进行打断,打断的方法根据曲线的不同采用不同的方法,主要采用entmake方法和ax方法,仅对Spline采用break的方法,因为我还没找到使用entmake和ax打断Spline的方法!
  经测试,当选择约290个曲线,其交点个数约为2500个时,采用Break方法耗时近184秒,而不采用Break方法仅需11秒钟!两者效率差别,显而易见!
   

本帖子中包含更多资源

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

x

点评

我也想过用entmake处理,但是不同类型的图元造成的分支太多了,为了凑合用,先用break命令了,虽然我极其讨厌在lisp里使用command和vl-cmdf.  发表于 2011-10-20 22:24

评分

参与人数 1明经币 +1 收起 理由
zzl9105 + 1

查看全部评分

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

本版积分规则

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

GMT+8, 2025-6-8 20:59 , Processed in 0.168355 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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