明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 909|回复: 9

[函数] 图框位置(图幅位置)排序函数

[复制链接]
发表于 2025-6-18 08:15:55 | 显示全部楼层 |阅读模式
  1. ;;;---------------------------------------------;;;
  2. ;;; 图框位置(图幅位置)排序函数(HLCAD/USER2128,2025-6-17)
  3. ;;; 函数主要用于多个图幅集合图纸的排序.
  4. ;;; 参数: pt_lst = '((图幅1左下点 图幅1右上点 图幅1比例 ... ) ... )
  5. ;;; 返回: 已排序后的总表(格式同pt_lst).
  6. (defun sort_pt_lst (pt_lst / BOX BOX$ LST$ MAX$ TAKE TF-LST TMP
  7.         HL:PtInorOut4Box tmp:take )
  8. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9. ;;; 判断Pt点是否在LL,UR的矩形框内.
  10. ;;; 如果Pt在框内,或边线上,返回:T.
  11. ;;; 参数LL,UR仅是矩形对角两点就行.
  12. ;;; EX: (HL:PtInorOut4Box (getpoint"\n测点:")(getpoint"\n角点1:")(getpoint"\n角点2:"))
  13. (defun HL:PtInorOut4Box (Pt LL UR)
  14.   (vl-every '>= (mapcar '* (mapcar '- Pt LL) (mapcar '- UR Pt)) '(0 0))
  15.   )
  16. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  17. ;;; 从图幅集Lst中提取box区域中所包含的所有图幅:
  18. ;;; 返回(box区域中所含图幅表 剩余Lst中的图幅表)
  19. (defun tmp:take (box Lst / Loop Rest take tmp)
  20.   (setq take nil)
  21.   (setq Rest Lst)
  22.   (setq Loop t)
  23.   (while Loop
  24.     (setq tmp (mapcar '(lambda(x)
  25.       (cond
  26.   ((and (apply 'HL:PtInorOut4Box (cons (cadr x) box)) ;右上点.
  27.         (apply 'HL:PtInorOut4Box (cons (car  x) box)) ;左下点.
  28.         )
  29.    (setq take (cons x take))
  30.    nil) ;完全包含.
  31.   ((apply 'HL:PtInorOut4Box (cons (cadr x) box)) ;右上点.
  32.    (setq box (list (cons (caar box) (cdar x)) (cadr box)))
  33.    (setq take (cons x take))
  34.    nil) ;图幅向下凸出.
  35.   (t x)
  36.   )) Rest))
  37.     (setq tmp (vl-remove 'nil tmp))
  38.     (if (> (length Rest) (length tmp))
  39.       (setq Rest tmp)
  40.       (setq Loop nil)
  41.       )
  42.     )
  43.   (list take Rest)
  44.   )
  45. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  46. ;;; 计算所有图幅集合所在区域的左下点、右上点:
  47.   (setq max$ (mapcar '(lambda(a b) (apply 'mapcar(cons a b)))
  48.          '(min max)
  49.          (list (mapcar 'car pt_lst) (mapcar 'cadr pt_lst))
  50.          ))
  51. ;;; 按右上角点的Y值最大在前(Y值相同,大图在前)进行排序:
  52.   (setq pt_lst (vl-sort pt_lst
  53.   '(lambda (a b)
  54.   (if (equal (cadadr a) (cadadr b))
  55.     (< (cadar  a) (cadar  b))
  56.     (> (cadadr a) (cadadr b))
  57.     ))))
  58.   (setq Lst$ pt_lst)
  59.   (setq tf-Lst '())
  60.   (while Lst$
  61. ;;; 提取顶行所包含的所有图幅:
  62.     (setq box$ (list (caar Lst$) (cadar Lst$)))
  63.     (setq box$ (list (cons (caar  max$) (cdar  box$))
  64.          (cons (caadr max$) (cdadr box$))
  65.          ))
  66.     (setq tmp (tmp:take box$ Lst$))
  67.     (setq tf-Lst (append tf-Lst (list (car tmp))))
  68.     (setq Lst$ (cadr tmp))
  69.     )
  70. ;;; 对各行图幅排序: 左先、上前
  71.   (setq tmp (mapcar '(lambda(x) (vl-sort x '(lambda (a b)
  72.       (cond
  73.   ((equal (* (+ (caadr a) (caar a)) 0.5) ;X值中位.
  74.     (* (+ (caadr b) (caar b)) 0.5)
  75.     (* (- (caadr a) (caar a)) 0.5) ;误差=X差值的一半.
  76.     )
  77.    (> (cadar a) (cadar b)) ;y值大者放前.
  78.    )
  79.   (t (< (caar a)(caar b))) ;x值小者放前.
  80.   )))) tf-Lst))
  81.   (setq tf-Lst (apply 'append tmp))
  82.   )
  83. ;;;---------------------------------------------;;;
  84. ;;; 函数sort_pt_lst测试程序(采用"函数Sort_pt_Lst.dwg"文件测试):
  85. (defun c:tt (/ Lst pts ss str tmp)
  86.   (vl-cmdf "_.zoom" "_e")
  87.   (setq SS (ssget "x" '((0 . "LWPOLYLINE") (8 . "02")))) ;图中所有图幅边框.
  88.   (setq Lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS))))
  89.   (setq pts (mapcar '(lambda(x / tmp) ;各图幅边框的(左下点 右上点).
  90.   (setq tmp (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= 10 (car x))) (entget x))))
  91.   (list (car tmp) (caddr tmp))
  92.   ) Lst))
  93.   (setq str (mapcar '(lambda(x / tmp) ;各图幅中标识字符(仅单个字符).
  94.   (setq tmp (ssget "_c" (car x) (cadr x) '((0 . "TEXT"))))
  95.   (cdr (assoc 1 (entget (ssname tmp 0))))
  96.   ) pts))
  97.   (setq Lst (mapcar '(lambda(x y) (append x (list y))) pts str))
  98.   (setq Lst (sort_pt_lst Lst))
  99.   (mapcar 'caddr Lst)
  100.   )
  101. ;;;---------------------------------------------;;;



本帖子中包含更多资源

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

x

评分

参与人数 3明经币 +3 收起 理由
lee50310 + 1 很给力!
这只胆小鬼 + 1 很给力!
xyp1964 + 1 赞一个!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
回复

使用道具 举报

发表于 2025-6-18 08:59:52 | 显示全部楼层
谢谢分享原创代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-18 09:18:17 | 显示全部楼层
这种多个图幅的排序方式困扰了我很多年,偶获思路,特分享给有需要的人
回复 支持 反对

使用道具 举报

发表于 2025-6-18 13:59:24 | 显示全部楼层
嗯,这个不错,在批量打印中,图框打印顺序有用。
回复 支持 反对

使用道具 举报

发表于 2025-6-19 18:30:24 | 显示全部楼层
这个应该是图框分行处理     按照最大的两个图框的y值范围    分成上下两组   然后分别排序   再合并
回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-20 10:55:23 | 显示全部楼层
本帖最后由 USER2128 于 2025-6-20 10:57 编辑
guosheyang 发表于 2025-6-19 18:30
这个应该是图框分行处理     按照最大的两个图框的y值范围    分成上下两组   然后分别排序   再合并

你说的是对的。
但仅采用常规排序函数排序后,其结果不尽人意。
回复 支持 反对

使用道具 举报

发表于 2025-6-20 11:32:08 | 显示全部楼层
本帖最后由 guosheyang 于 2025-6-20 18:15 编辑
USER2128 发表于 2025-6-20 10:55
你说的是对的。
但仅采用常规排序函数排序后,其结果不尽人意。

每组中  先按 x值由小到大排列   当x相同时  再按照y值由大到小排    这里的 x值相同否   涉及到容差的设定   而容差  又可以计算每组中所有  图框对(两两比较)  起点(图框左下角点)坐标x值差的绝对值的  最小值再加上1mm来确定  
回复 支持 反对

使用道具 举报

发表于 2025-6-21 12:06:16 | 显示全部楼层

本帖子中包含更多资源

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

x

评分

参与人数 1明经币 +1 收起 理由
USER2128 + 1 很给力!

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2025-6-21 16:26:00 | 显示全部楼层

大佬的动画做出来就是牛!
回复 支持 反对

使用道具 举报

发表于 2025-6-23 09:07:31 | 显示全部楼层
本帖最后由 xyp1964 于 2025-6-23 09:12 编辑
USER2128 发表于 2025-6-21 16:26
大佬的动画做出来就是牛!

;; 这样表达更合理


本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 09:29 , Processed in 0.196286 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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