SteveK 发表于 2022-7-6 12:49:27

帮助排序不同的高度

嗨,我想写一个程序,返回一个特定级别的所有实体的列表。我所拥有的是文本的级别(可能有4个级别高),每个级别都在列中,尽管它们之间的距离不同。请参阅随附的jpeg以了解想法。
 
在每列中,文本居中,具有相同的对齐X坐标(即在DXF组码11中),Y坐标的间距相等。文本列在X或Y方向上彼此之间没有公共距离。
 
因此,我希望我能得到帮助的是,返回一个特定级别上所有实体的列表(即jpeg中的颜色编码)的代码,该列表依赖于开始时设置的级别变量。例如,如果我将这个变量设置为1,它将返回jpeg中黄色的实体(最好按X坐标排序)。变量设置为3将返回绿色实体。(注意,我正在处理的文本不像jpeg那样进行颜色编码)
 
如果没有其他东西,我甚至欢迎伪代码。我目前的想法是:
-创建具有公共X坐标的实体列表。(虽然如果有数百条这样的文本,我不知道该如何存储它们)
-然后按Y坐标对这些列表进行排序,并根据级别变量返回实体。如果级别变量设置为4,并且实体不存在,则它将跳过该列/列表。
 
谢谢你的帮助
 
 
注:我认为这不是很有帮助(我更希望有全新的代码),但这里是我写的。此代码不考虑级别变量,只返回最高文本实体的列表。它变得太乱了,无法再添加任何其他内容。
(defun txtlst (ss / ssLst topEnt highestPoleTextLst)

(setq ssLst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))

   (foreach e1 ssLst
   (setq lst (cons e1 lst))
   (foreach e2 ssLst
   (If (= (cadr (assoc 11 (entget e1))) (cadr (assoc 11 (entget e2))))
       (setq lst (cons e2 lst))))
   (foreach en lst
   (If topEnt
       (If (< (caddr (assoc 11 (entget topEnt))) (caddr (assoc 11 (entget en))))
         (setq topEnt en))
       (setq topEnt en)))
   (If highestPoleTextLst
   (foreach en highestPoleTextLst
       (If (eq topEnt en)
         (If (< (caddr (assoc 11 (entget topEnt))) (caddr (assoc 11 (entget en))))
       (subst en topEnt highestPoleTextLst)
       (setq topEnt nil)))))
   (If topEnt (setq highestPoleTextLst (cons topEnt highestPoleTextLst)))
   (setq lst nil)
   )

highestPoleTextLst
)   

Lee Mac 发表于 2022-7-6 13:04:50

Steve-快速提示:查看vl排序函数

Lee Mac 发表于 2022-7-6 13:12:02

您想要完成的任务的一个类似示例是在这个线程中,将圆排序为行:
 
http://www.cadtutor.net/forum/showthread.php?t=36284

Patrick_35 发表于 2022-7-6 13:19:17

你好
 
一个例子
 

(defun trier_xy(/ add ele lst tab txt x)
(defun add()
   (setq ele (vl-sort ele '(lambda(a b)(< (cadr (vlax-get a 'insertionpoint))(cadr (vlax-get b 'insertionpoint))))))
   (if tab
   (setq tab (cons ele tab))
   (setq tab (list ele))
   )
)

(if (ssget (list (cons 0 "TEXT,MTEXT")))
   (progn
   (vlax-for txt (setq sel (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))
   (setq lst (cons txt lst))
   )
   (vla-delete sel)
   (foreach txt (vl-sort lst '(lambda(a b)(< (car (vlax-get a 'insertionpoint))(car (vlax-get b 'insertionpoint)))))
   (if (eq (car (vlax-get txt 'insertionpoint)) x)
   (setq ele (cons txt ele))
   (progn
       (add)
       (setq x (car (vlax-get txt 'insertionpoint))
         ele (list txt)
       )
   )
   )
   )
   (add)
   )
)
(reverse tab)
)

+

SteveK 发表于 2022-7-6 13:25:36

嘿,谢谢,你们总是帮我渡过难关。
 
我试着用你的例子,帕特里克。编辑:效果很好!再次感谢。
 
李,谢谢你的提示;关于vl排序,我认为这是不可能的,但可以肯定的是,不能有一个vl排序函数同时按X和Y排序?
我知道使用两个vl排序函数(我应该使用)按一个排序,然后按另一个排序;当使用第二个vl排序函数时,第一个vl排序函数的顺序是否有可能被否定?

Lee Mac 发表于 2022-7-6 13:33:10

我只需要使用一个vl排序,并使用一个选择集来收集与某些文本具有相同x坐标的所有文本进行比较,例如:
 

(if (setq ss (ssget "_X" '((0 . "TEXT,MTEXT"))))
(while (not (zerop (sslength ss)))
   (setq tEnt (ssname ss 0))
   (if (setq nss (ssget "_X" (list '(0 . "TEXT,MTEXT")
                                 '(-4 . "=,*,*") (assoc 11 (entget tEnt)))))
   (progn

       (setq sorted (vl-sort
                      (mapcar 'cadr (ssnamex nss))
                        (function
                        (lambda (a b)
                            (< (caddr (entget a)) (caddr (entget b)))))))

       (mapcar
         (function
         (lambda (x)
             (ssdel x ss))) sorted)

       )
   )
   )
)
                  

SteveK 发表于 2022-7-6 13:48:12

我不知道ssget过滤器可以这样使用。这很有帮助,谢谢。
 
问题是,如果我想手动选择选择集(即删除“_X”)并只选择一次,该怎么办?
 
此外,线路:
如果其他人使用你的代码,你的意思是:
4

Lee Mac 发表于 2022-7-6 13:52:44

 
这将稍微困难一些,因为第二个选择集检索数据库中满足要求的所有文本,因此如果用户不再次选择文本,则很难对其进行过滤。
 
另一种方法是使用“_X”方法获取实体列表,然后提示用户进行选择,并删除列表中不在用户选择集中的实体:眨眼:
 
 
是的,对不起-我写得很快。。。似乎太快了。。
页: [1]
查看完整版本: 帮助排序不同的高度