broncos15 发表于 2022-7-5 16:30:57

大型sele的LISP效率

我试图找出处理大型选择集的最有效方法,在这里我测试对象是否与其他对象相交。基本上,我逐个处理选择集,测试哪些对象与哪些对象相交,然后在交点处放置一个圆。现在,我基本上只是重复很多次
(if (safearray-value (variant-value (vla-intersectwith obj1 objt2 acExtendNone)))。例如,如果我有5个对象,(1,2,3,4,5)我从对象1开始,测试它是否与对象2,3,4和5相交。然后我转到对象2,看看它是否与对象1、3、4和5相交,依此类推。有没有更快的方法来实现这一点,因为它真的很慢,特别是必须将所有对象转换为vla对象。

Grrr 发表于 2022-7-5 16:42:38

也许可以试试集合之间的LM交集。
他使用vlax invoke调用intersectwith方法,该方法跳过了safearray转换。此外,除非获得选择集vla对象,否则将SS内的珐琅转换为vla对象是不可避免的。

Roy_043 发表于 2022-7-5 16:45:00

无需检查对象1和对象2之间的交点,这已在第一步中完成。
1 -> (2 3 4 5)
2 -> (3 4 5)
3 -> (4 5)
4 -> (5)

broncos15 发表于 2022-7-5 16:53:17

谢谢你们俩的帮助!我一定会使用李的方法。我试图为每个重复函数将整个选择集分成2个,但我做错了什么。到目前为止,我的代码是
我写它的方式是让ss1是单个实体,ss2是其余的实体,然后找到交点,插入点,从ss2中删除第一个实体(这样我就不会犯对同一个对象进行多次比较的错误)。我做错了什么?

Stefan BMR 发表于 2022-7-5 16:55:50

野马队,
 
将ss1设置为nil(在代码末尾)会在第二次迭代中导致错误。应该是这样的
(setq ss1 (ssadd))此外
(setq ss1 (ssadd (ssname ss cnt1)))错误。正确的语法是
(ssadd (ssname ss cnt1) ss1)您不需要(setq s1…,只需向选择集添加一个实体。
 
即使更正了这些错误,您的代码也无法工作,因为(setq ss2 ss)没有创建不同的选择集。ss2和ss是指向同一选择集的指针。
最终,cnt1变得大于ss中的对象数,因此存在误差。
 
如果您打算使用代码,可以使用以下简单构造:
或者您可以使用LeeMac站点的功能(LM:intersectionsinset sel)。
 
我对该主题的贡献:
(defun all_int ( ss / i lst en l x int p)
(repeat (setq i (sslength ss))
   (setq lst (cons (vlax-ename->vla-object (ssname ss (setq i (1- i)))) lst))
)
(while (cdr lst)
   (setq x (car lst) lst (cdr lst))
   (foreach e lst
   (setq int (vlax-invoke x 'IntersectWith e acExtendNone))
   (while int
       (setq l (cons (list (car int) (cadr int) (caddr int)) l)
             int (cdddr int)
       )
   )
   )
)
l
)和测试功能
8

broncos15 发表于 2022-7-5 17:04:12

Stefan,非常感谢你提供的信息!我想学习和提高我的LISP写作技能,所以所有关于ssadd和ssdel的信息都非常有用!我会继续摆弄代码(我喜欢看到不同的编写方法来提高我的技能),但你的代码工作得很好(和李的一样)。再次感谢您的帮助!

broncos15 发表于 2022-7-5 17:11:35

所以我已经准备好了我的代码并在运行,但问题是,对于相当大的选择集,代码速度非常慢。例如,当我有一个大约500个对象的选择集时,运行需要2分钟。执行visual lisp选择集(即vla selectOnScreen)的效率会提高多少?有没有其他方法我也可以使用,但我没有想到?

Lee Mac 发表于 2022-7-5 17:17:20

如果我正确理解了您希望获得选择集中所有对象之间的所有交点,我建议您使用我的集内交点函数(请参阅包含如何评估该函数示例的测试程序)。除了在计算交点时立即生成点实体外,我认为没有任何方法可以进一步提高该函数的效率(我当然愿意接受建议!)。
 
编辑:抱歉Stefan-我忽略了你已经建议了这个功能。

broncos15 发表于 2022-7-5 17:21:27

李,你的程序就是我最终使用的程序(我画圆而不是点,并做一些其他的事情,但这是最初程序的要点)。就我自己的理解而言,使用ssget,然后将选择集转换为vla对象,还是创建visual lisp选择集更有效?我总是使用ssget,因为它非常简单,但如果visual lisp方法更快,我将使用对象列表函数中的交点。再次感谢您的帮助和所有非常有用的功能!

Lee Mac 发表于 2022-7-5 17:27:46

 
你可能有一个有效的观点-
我还没有测试vlax ename->vla对象函数的效率,因此这种转换可能是处理过程中的一个瓶颈。
 
也许您可以将性能与此备选方案进行比较:
9
页: [1] 2
查看完整版本: 大型sele的LISP效率