ketxu 发表于 2022-7-6 09:05:47

[帮助]按di对列表点排序

我有一个点列表(x y z)。现在,我想从列表中的一个点(变量)开始绘制一条样线,转到下一个点,使该点到下一个点的距离为最小,然后重复直到结束
由于我的E很差,我在这里贴了一张照片。我收到了来自用户排序为列表的列表点
(1 2 3 4 5 6 7在屏幕上,现在我想重新排序,就像(1 2 6 7 8 5 4 3)
我尝试了一些循环,但在lisp中很难成为新手。请帮帮我,(可以用递归吗?)

谢谢大家的阅读

BlackBox 发表于 2022-7-6 09:15:16

这应该让你开始:
 
(defun _SortPtListByDist(ptList)
;; Argument: Point list
;; Returns: Point list, sorted by distance from first point
(vl-load-com)
(mapcar
   '(lambda (x / ptList2)
      (setq ptList2 (append (cdr x) ptList2)))
   (vl-sort
   (mapcar
       '(lambda (x / pt ptlist2)
          (setq ptlist2
               (append
                   (cons
                     (distance
                     (cond
                         (pt)
                         ((setq pt (car ptList))))
                     x)
                     x)
                   ptlist2)))
       ptList)
   '(lambda (x y)
      (< (car x) (car y))))))
 
例子:
 
(defun _GetPoints(/ pt ptList)
;; Returns: Point list
(while (/= nil (setq pt (getpoint)))
      (setq ptList (cons pt ptList)))
(reverse ptList))
 
(_SortPtListByDist (_GetPoints))
 
希望这有帮助!

alanjt 发表于 2022-7-6 09:18:58

Mat,您可以通过以下方式减少排序过程。。。
 
(defun sortMyNitchUp (pointlist)
((lambda (point) (cons point (vl-sort (cdr pointlist) '(lambda (a b) (< (distance point a) (distance point b))))))
   (car pointlist)
)
))

David Bethel 发表于 2022-7-6 09:21:23

这将充满问题:
 

(defun ptl2pol (pl / fl mx md p1 p2 tp)

(defun remove (expr lst);;;TonyT or VNesterowski
   (apply 'append (subst nil (list expr) (mapcar 'list lst))))

(setq mx 0)
(foreach p pl
   (foreach v pl
      (if (> (distance p v) mx)
          (setq mx (distance p v) p1 p p2 v))))
(setq fl (list p1))
(setq pl (remove p1 pl))

(repeat (length pl)
    (setq md (distance p1 p2))
    (foreach v pl
       (if (< (distance (car fl) v) md)
         (setq md (distance (car fl) v)
               tp v)))
    (setq fl (cons tp fl))
    (setq pl (remove tp pl)))

(command "_.PLINE")
(foreach v (reverse fl)
      (command v))
(command "")
(prin1))

 
 
所有点必须在同一平面上
 
如果两个点与另一个点的距离相同怎么办?
 
举几个例子。
 
对于大型列表,这将非常缓慢。
 
HTH-David

Lee Mac 发表于 2022-7-6 09:28:58

效率不高,但这不是预期的结果吗:
 
(defun sort ( lst / _sort )
(defun _sort ( a b )
   (if a (cons a (_sort (car (setq b (vl-sort b '(lambda ( c d ) (< (distance a c) (distance a d)))))) (cdr b))))
)
(_sort (car lst) (cdr lst))
)
 
还是我误解了?

ketxu 发表于 2022-7-6 09:35:19

哇,非常感谢大家。这都是我所期待的。太棒了我花了一天时间思考和编码,但和你在一起需要几个小时^^
再次感谢大家
 
@大卫,李:没问题
 
@alanjt,RenderMan:我用bellow列表进行了测试,觉得它包含一个mis
 
并制作一个pline:

Lee Mac 发表于 2022-7-6 09:39:22

实际上,David的算法给出了更好的结果,因为最佳顺序也取决于起点。
 
下面的列表是区分算法的一个很好的示例:
 
使用Alan/Renderman的方法:
 

 
以上代码:
 

 
上面有David的代码:
 

 
这是选择正确的起点开始算法的结果。因此,我可以通过以下方法改进代码:
 
(defun sort ( lst / _sort a b d e l p )
(defun _sort ( a b )
   (if a (cons a (_sort (car (setq b (vl-sort b '(lambda ( c d ) (< (distance a c) (distance a d)))))) (cdr b))))
)
(setq l (cdr lst)
       d (distance (setq p (car lst)) (car l))
)
(while (setq a (car l))
   (foreach b (setq l (cdr l))
   (if (< d (setq e (distance a b))) (setq p a d e))
   )
)
(_sort p (vl-remove p lst))
)现在导致:
 

 
但是,虽然更简洁,但由于其递归性质,我的可能远不如David的高效。

alanjt 发表于 2022-7-6 09:42:54

好吧,我想这就是我没有阅读线程,只看发布的代码得到的。英雄联盟

BlackBox 发表于 2022-7-6 09:47:08

 
实际上,我根据OP指定的布局绘制点,并考虑了特定的点选择顺序(同样,根据OP)。

ketxu 发表于 2022-7-6 09:53:58

@李:我试着从列表中的第一个点绘制pline(如果用户选择的不是第一个点,我会把它放在列表中^^)
所以你的第一种方法就是我需要的^^
我还写了一个方法来做同样的事情:
8
 
对于Lee post中的list,我希望它像(sort lst 0)和Lee method像(sort lst 10)。
这是“普通”方式,但我觉得它比其他方式快一点??它是?
 
附言:@RenderMen:OP的意思是??对不起,我的英文不太好,所以,我很难理解“缩写”(我用谷歌写任何字符)
页: [1] 2
查看完整版本: [帮助]按di对列表点排序