明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: 韩飞翔

[函数] 选择集排序8式

[复制链接]
发表于 2023-12-5 13:31:32 | 显示全部楼层
感谢大佬分享~~
发表于 2023-12-6 17:23:54 | 显示全部楼层
韩飞翔 发表于 2023-12-4 12:03
程序不缺函数,只是函数写在排序函数内,然后子函数作为可变变量清空了,鉴于初学者不会改代码,直接给你改 ...

可以用激情换明经币的呀
 楼主| 发表于 2023-12-6 18:22:51 | 显示全部楼层
本帖最后由 韩飞翔 于 2023-12-6 18:28 编辑
qazxswk 发表于 2023-12-6 17:23
可以用激情换明经币的呀

哦,知道了
发表于 2023-12-11 11:07:40 | 显示全部楼层
还是谢谢分享了。
发表于 2023-12-11 11:53:19 | 显示全部楼层
                                   牛
                         牛       牛
                      牛 牛 牛 牛 牛 牛
                   牛             牛
                         牛 牛 牛 牛 牛

发表于 2023-12-11 15:50:32 | 显示全部楼层
本帖最后由 e2002 于 2023-12-11 15:56 编辑

当初写批量创建 Layouts 工具的时候,也是需要这么个 左右上下 共8种排序方式(实际上是4种,另外四种是其他4种的倒序而已),为了简化代码,所以用了一点办法。大家共同学习提高,代码没有任何限制没有任何保证(包括商用),完全公开,无币可下载:







  1. ;; 边界列表的2次排序函数
  2.   (defun _lkpt_Layout_CreateByTitleBlocks_Sort ( / i1 sym1 i2 sym2 l_sort u v lReturn)
  3.     (cond
  4.       ( (= sSort "1") (setq i1 1 sym1 '> i2 0 sym2 '<) );;左到右,上到下
  5.       ( (= sSort "2") (setq i1 1 sym1 '< i2 0 sym2 '<) );;左到右,下到上
  6.       ( (= sSort "3") (setq i1 1 sym1 '> i2 0 sym2 '>) );;右到左,上到下
  7.       ( (= sSort "4") (setq i1 1 sym1 '< i2 0 sym2 '>) );;右到左,下到上
  8.       ( (= sSort "5") (setq i1 0 sym1 '< i2 1 sym2 '>) );;上到下,左到右
  9.       ( (= sSort "6") (setq i1 0 sym1 '> i2 1 sym2 '>) );;上到下,右到左
  10.       ( (= sSort "7") (setq i1 0 sym1 '< i2 1 sym2 '<) );;下到上,左到右
  11.       ( (= sSort "8") (setq i1 0 sym1 '> i2 1 sym2 '<) );;下到上,右到左
  12.     );_cond
  13.     (setq l_sort (vl-sort lBoundarys (function (lambda (u v) ((vl-symbol-value sym1) (nth i1 (car u)) (nth i1 (car v)))))) );_第一次排序
  14.     (setq l_sort (vl-sort l_sort (function (lambda (u v)
  15.                                              (if (< (abs (- (nth i1 (car u)) (nth i1 (car v)))) rFuzzy)
  16.                                                ((vl-symbol-value sym2) (nth i2 (car u)) (nth i2 (car v)))
  17.                                                nil
  18.                                              );_fi
  19.                                            );_lam
  20.                                  );_fun
  21.                  )
  22.     );_第二次排序
  23.     (setq lReturn l_sort)
  24.   );_defun _lkpt_Layout_CreateByTitleBlocks_Sort

本帖子中包含更多资源

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

x
回复 支持 1 反对 0

使用道具 举报

发表于 2023-12-11 16:00:48 | 显示全部楼层
关于为什么要分开两次排序:
最初是写为一次排序,在条件中判断x,y两个值,然而结果就是会出现问题,按理应该是不会出现错误的,后来我怀疑是vl-sort的问题,然后自己重写了一个专门针对这个x,y坐标值两个条件来排序的函数,就不会出错了,因此,应该是 vl-sort的问题。记得当时和Qf还讨论过vl-sort的这个bug。

点评

好  发表于 2023-12-11 16:17
回复 支持 1 反对 0

使用道具 举报

发表于 2024-5-11 16:20:54 | 显示全部楼层
e2002 发表于 2023-12-11 16:00
关于为什么要分开两次排序:
最初是写为一次排序,在条件中判断x,y两个值,然而结果就是会出现问题,按理 ...


翻了您的回复记录没找到您提到的vl-sort的问题。
能帮我看看 这个代码是有什么问题吗,问了chatgpt也没给我解决。
TT1函数是正常的“123” TT2函数的顺序就不正常了“321654”,会颠倒嵌套内部的选择集顺序
  1. (defun c:TT1 ()
  2.   (setq SS (ssget)) ; 获取用户选择的选择集
  3.         (setq SS2 (SORT-RIGHT2LEFT SS 0 nil))
  4.         ;(setq SS2 (SORT-DOWN2UP (SORT-RIGHT2LEFT SS 0 nil) 0 nil))
  5.         ;(setq SS2 (SORT-SE SS 10 0 0 nil) )
  6.         (printSelectionSetText SS2)
  7.   (princ)
  8. )
  9. (defun c:TT2 ()
  10.   (setq SS (ssget)) ; 获取用户选择的选择集
  11.         ;(setq SS2 (SORT-RIGHT2LEFT SS 0 nil))
  12.         (setq SS2 (SORT-DOWN2UP (SORT-RIGHT2LEFT SS 0 nil) 0 nil))
  13.         ;(setq SS2 (SORT-SE SS 10 0 0 nil) )
  14.         (printSelectionSetText SS2)
  15.   (princ)
  16. )


  17. (defun printSelectionSetText (ss / len i ent data text)
  18.   (setq len (sslength ss)) ; 获取选择集中对象的数量
  19.   (setq i 0)
  20.   (repeat len
  21.     (setq ent (ssname ss i)) ; 获取选择集中的下一个对象
  22.     (setq data (entget ent)) ; 获取对象的数据
  23.     (setq text (cdr (assoc 1 data))) ; 获取文本内容,假设对象是文本实体
  24.     (princ text) ; 输出文本内容
  25.     (setq i (1+ i))
  26.   )
  27.   (princ)       
  28. )
  29. (defun SORT-RIGHT2LEFT (SE FUZZ K / ENT INDEX LST NEWLST NEWSE TMP X)
  30.         (setq DXF 10)
  31.         (SETQ INT 0)
  32.   (setq LST   '() ;; 初始化空列表LST
  33.                 INDEX 0 ;; 初始化索引INDEX为0
  34.   )
  35.   (repeat (sslength SE)  ;; 根据SE的长度进行循环
  36.     (setq ENT (entget (ssname SE INDEX)) ;; 获取SE中指定索引处的实体信息,并赋值给ENT
  37.                         TMP (cdr (assoc DXF ENT)) ;; 从实体信息中提取DXF对应的值,并赋值给TMP
  38.     )
  39.     (if
  40.       (and
  41.         INT ;; 如果INT存在且不为nil
  42.         (= (type INT) 'INT) ;; 且INT的类型为INT
  43.         (= (type TMP) 'list) ;; 且TMP的类型为列表
  44.         (< INT (length TMP)) ;; 且INT小于TMP列表的长度
  45.       )
  46.       (setq TMP (nth INT TMP)) ;; 则将TMP的第INT个元素赋值给TMP
  47.     )
  48.     (setq LST (cons  ;; 将包含TMP值和实体信息第5项值的列表作为新元素,加入到LST列表中
  49.                 (list TMP (cdr (assoc 5 ENT)))
  50.                 LST
  51.               )
  52.     )
  53.     (setq INDEX (1+ INDEX)) ;; 索引自增1
  54.   )
  55.         ;; 排序操作
  56.         (if
  57.                 (and
  58.                         FUZZ ;; 如果FUZZ存在且不为nil
  59.                         (or
  60.                                 (= (type FUZZ) 'INT) ;; 且FUZZ的类型为INT
  61.                                 (= (type FUZZ) 'REAL) ;; 或FUZZ的类型为REAL
  62.                         )
  63.                         (or
  64.                                 (= (type TMP) 'INT) ;; 且TMP的类型为INT
  65.                                 (= (type TMP) 'REAL) ;; 或TMP的类型为REAL
  66.                         )
  67.                 )
  68.                 (setq NEWLST (vl-sort  ;; 如果满足条件,则对LST列表进行排序,排序规则为加入FUZZ后比较
  69.                                                                          LST
  70.                                                                          (function
  71.                                                                                  (lambda (E1 E2)
  72.                                                                                          (> (+ (car E1) FUZZ) (car E2))
  73.                                                                                  )
  74.                                                                          )
  75.                                                                  )
  76.                 )
  77.                 (setq NEWLST (vl-sort  ;; 否则对LST列表进行排序,按照原始值比较
  78.                                                                          LST
  79.                                                                          (function
  80.                                                                                  (lambda (E1 E2)
  81.                                                                                          (> (car E1) (car E2))
  82.                                                                                  )
  83.                                                                          )
  84.                                                                  )
  85.                 )
  86.         )
  87.   ;; 如果K为T,则倒置
  88.   (if K  ;; 如果K为真
  89.     (setq NEWLST (reverse NEWLST)) ;; 则将NEWLST列表倒置
  90.   )
  91.   ;; 组织排序后的选择集
  92.   (setq NEWSE (ssadd)) ;; 初始化新的选择集NEWSE
  93.   (foreach TMP NEWLST  ;; 遍历NEWLST
  94.     (setq NEWSE (ssadd (handent (cadr TMP)) NEWSE)) ;; 将每个元素对应的实体添加到NEWSE中
  95.   )
  96.   ;; 返回值
  97.   NEWSE ;; 返回NEWSE作为函数的返回值
  98. )


  99. (defun SORT-DOWN2UP (SE FUZZ K / ENT INDEX LST NEWLST NEWSE TMP Y)
  100.         (setq DXF 10)
  101.         (SETQ INT 1)
  102.   (setq LST   '() ;; 初始化空列表LST
  103.                 INDEX 0 ;; 初始化索引INDEX为0
  104.   )
  105.   (repeat (sslength SE)  ;; 根据SE的长度进行循环
  106.     (setq ENT (entget (ssname SE INDEX)) ;; 获取SE中指定索引处的实体信息,并赋值给ENT
  107.                         TMP (cdr (assoc DXF ENT)) ;; 从实体信息中提取DXF对应的值,并赋值给TMP
  108.     )
  109.     (if
  110.       (and
  111.         INT ;; 如果INT存在且不为nil
  112.         (= (type INT) 'INT) ;; 且INT的类型为INT
  113.         (= (type TMP) 'list) ;; 且TMP的类型为列表
  114.         (< INT (length TMP)) ;; 且INT小于TMP列表的长度
  115.       )
  116.       (setq TMP (nth INT TMP)) ;; 则将TMP的第INT个元素赋值给TMP
  117.     )
  118.     (setq LST (cons  ;; 将包含TMP值和实体信息第5项值的列表作为新元素,加入到LST列表中
  119.                 (list TMP (cdr (assoc 5 ENT)))
  120.                 LST
  121.               )
  122.     )
  123.     (setq INDEX (1+ INDEX)) ;; 索引自增1
  124.   )
  125.         ;; 排序操作
  126.         (if
  127.                 (and
  128.                         FUZZ ;; 如果FUZZ存在且不为nil
  129.                         (or
  130.                                 (= (type FUZZ) 'INT) ;; 且FUZZ的类型为INT
  131.                                 (= (type FUZZ) 'REAL) ;; 或FUZZ的类型为REAL
  132.                         )
  133.                         (or
  134.                                 (= (type TMP) 'INT) ;; 且TMP的类型为INT
  135.                                 (= (type TMP) 'REAL) ;; 或TMP的类型为REAL
  136.                         )
  137.                 )
  138.                 (setq NEWLST (vl-sort  ;; 如果满足条件,则对LST列表进行排序,排序规则为加入FUZZ后比较
  139.                                                                          LST
  140.                                                                          (function
  141.                                                                                  (lambda (E1 E2)
  142.                                                                                          (< (+ (car E1) FUZZ) (car E2))
  143.                                                                                  )
  144.                                                                          )
  145.                                                                  )
  146.                 )
  147.                 (setq NEWLST (vl-sort  ;; 否则对LST列表进行排序,按照原始值比较
  148.                                                                          LST
  149.                                                                          (function
  150.                                                                                  (lambda (E1 E2)
  151.                                                                                          (< (car E1) (car E2))
  152.                                                                                  )
  153.                                                                          )
  154.                                                                  )
  155.                 )
  156.         )
  157.   ;; 如果K为T,则倒置
  158.   (if K  ;; 如果K为真
  159.     (setq NEWLST (reverse NEWLST)) ;; 则将NEWLST列表倒置
  160.   )
  161.   ;; 组织排序后的选择集
  162.   (setq NEWSE (ssadd)) ;; 初始化新的选择集NEWSE
  163.   (foreach TMP NEWLST  ;; 遍历NEWLST
  164.     (setq NEWSE (ssadd (handent (cadr TMP)) NEWSE)) ;; 将每个元素对应的实体添加到NEWSE中
  165.   )
  166.   ;; 返回值
  167.   NEWSE ;; 返回NEWSE作为函数的返回值
  168. )


本帖子中包含更多资源

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

x
发表于 2024-5-12 23:43:16 | 显示全部楼层
e2002 发表于 2023-12-11 15:50
当初写批量创建 Layouts 工具的时候,也是需要这么个 左右上下 共8种排序方式(实际上是4种,另外四种是其 ...

根据您的代码改写了一个SORT-XY函数,版权归原作者所有。


SORT-XY函数是一个AutoLISP函数,用于对AutoCAD中的实体进行排序,并根据排序结果创建一个新的选择集。函数的参数包括SE(选择集)、sSort(排序方式)、FUZZ(模糊匹配值)等。以下是SORT-XY函数的使用说明:

功能
SORT-XY函数将AutoCAD选择集中的实体根据指定的排序方式进行排序。排序依据是实体的坐标值和图元句柄。排序完成后,函数将创建一个新的选择集,包含排序后的实体。

参数
SE: 选择集,包含需要排序的AutoCAD实体。
sSort: 字符串,指定排序方式。共有8种排序方式,分别对应不同的坐标排序策略。
FUZZ: 数值,用于模糊匹配坐标值,当两个坐标值的差值小于或等于FUZZ时,将使用第二排序标准。
排序方式
"1": 左到右,上到下
"2": 左到右,下到上
"3": 右到左,上到下
"4": 右到左,下到上
"5": 上到下,左到右
"6": 上到下,右到左
"7": 下到上,左到右
"8": 下到上,右到左
使用步骤
使用AutoCAD的选择工具选择一组实体。
调用SORT-XY函数,并传入选择集、排序方式和FUZZ值。
函数将根据提供的排序方式对实体进行排序。
函数将创建一个新的选择集,包含排序后的实体。
示例
(SORT-XY SS 1 10)
排序方式为1,FUZZ值为10

返回值
SORT-XY函数返回一个新的选择集,包含排序后的实体。

值得学习的地方:将选择集转换为列表,只需要同时存储图元句柄就能反转换回去。


本帖子中包含更多资源

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

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

本版积分规则

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

GMT+8, 2024-11-25 17:48 , Processed in 0.198571 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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