明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
楼主: kucha007

【K:RtnBox4SSGroup】矩形分堆/方框分堆

  [复制链接]
发表于 2024-5-26 21:37:35 | 显示全部楼层
谢谢楼主分享!
发表于 2024-6-5 18:39:08 | 显示全部楼层
谢谢苦茶大神分享。请教一个问题,如果我想获得的是分堆后的选择集列表,应该怎么使用比较合适呢?
 楼主| 发表于 2024-6-5 19:53:56 | 显示全部楼层
hubeiwdlue 发表于 2024-6-5 18:39
谢谢苦茶大神分享。请教一个问题,如果我想获得的是分堆后的选择集列表,应该怎么使用比较合适呢?

ssget框选或者叉选啊(ssget “w” <pt1> <pt2> [filter-list])
发表于 2024-6-5 20:19:55 | 显示全部楼层
kucha007 发表于 2024-6-5 19:53
ssget框选或者叉选啊(ssget “w”   [filter-list])

这样有可能选中坐标范围内,选择集范围外的图元。
 楼主| 发表于 2024-6-5 20:38:06 | 显示全部楼层
hubeiwdlue 发表于 2024-6-5 20:19
这样有可能选中坐标范围内,选择集范围外的图元。

你一开始不就选择对象分堆了,怎么还会选择框之外的对象呢?
发表于 2024-6-5 20:52:06 | 显示全部楼层
kucha007 发表于 2024-6-5 20:38
你一开始不就选择对象分堆了,怎么还会选择框之外的对象呢?

一开始的选择集是过滤过的,每一个相交图元集合包围盒范围内可能有无关图元。分堆后,如果在通过ssget选择,会把无关图元选上。
 楼主| 发表于 2024-6-5 21:00:45 | 显示全部楼层
hubeiwdlue 发表于 2024-6-5 20:52
一开始的选择集是过滤过的,每一个相交图元集合包围盒范围内可能有无关图元。分堆后,如果在通过ssget选 ...

那你就不能把过滤条件再加上咩?ssget也可以,或者遍历选择集去掉也可以。
发表于 2024-6-5 21:22:04 | 显示全部楼层
kucha007 发表于 2024-6-5 21:00
那你就不能把过滤条件再加上咩?ssget也可以,或者遍历选择集去掉也可以。

有道理,谢谢,谢谢。
发表于 2024-6-8 12:24:41 | 显示全部楼层
本帖最后由 hubeiwdlue 于 2024-6-16 11:47 编辑

苦茶大师,有一小段代码感觉很复杂,读不太明白,做了简化,不知道对不对,试了几个图形,感觉也能分对。您帮忙看一下。
  1. ;对图元进行扎堆分组(矩形分堆),并返回每一个组的包围盒
  2. ;时间复杂度为n(1),测试了17万个图元480组仅10秒
  3. ;作者:Tryhi-大海 (优化 by Kucha)
  4. ;SS是选择集,Dist是方框之间的间隙容差。
  5. (defun K:RtnBox4SSGroup (SS Dist / K:GetEntBox K:GetSSBoxLst K:2RecIntersect Lst NewLst TmpLst Flag Rdo BasRec FstRec IntRec a b)
  6.   (progn ;基础函数
  7.     ;获取实体最小外接矩形的WCS坐标(忽略Z值)
  8.     (defun K:GetEntBox (en / MaxPt MinPt)
  9.       (vla-GetBoundingBox (vlax-ename->vla-object en) 'MinPt 'MaxPt) ;取得包容图元的最大点和最小点
  10.       (setq MinPt (vlax-safearray->list MinPt)) ;把变体数据转化为表
  11.       (setq MaxPt (vlax-safearray->list MaxPt)) ;把变体数据转化为表
  12.       (list (car MinPt) (cadr MinPt) (car MaxPt) (cadr MaxPt))
  13.     )
  14.     ;获取选择集每个实体的最小边界框坐标列表
  15.     (defun K:GetSSBoxLst (SS / i en Lst)
  16.       (if SS
  17.         (repeat (setq i (sslength SS))
  18.           (setq en (ssname SS (setq i (1- i))))
  19.           (setq Lst (cons (K:GetEntBox en) Lst))
  20.         )
  21.       )
  22.       Lst
  23.     )
  24.     ;如果矩形相交,则返回两矩形的最大边界框,否则,返回nil
  25.     (defun K:2RecIntersect (A B)
  26.       (if
  27.         (not
  28.           (or  ;不可能重叠的四种情况
  29.             (> (car A) (caddr B)) ;A的左侧比B的右侧大:X
  30.             (> (cadr A) (Last B)) ;A的下部比B的上部大:Y
  31.             (< (caddr A) (car B)) ;A的右侧比B的左侧小:X
  32.             (< (Last A) (cadr B)) ;A的上部比B的下部小:Y
  33.           )
  34.         )
  35.         (list
  36.           (min (car A) (car B))
  37.           (min (cadr A) (cadr B))
  38.           (max (caddr A) (caddr B))
  39.           (max (Last A) (Last B))
  40.         )
  41.       )
  42.     )
  43.   )
  44.   (if (and SS  (setq Dist (/ Dist 2)))
  45.     (progn
  46.       (setq Lst
  47.                                 (vl-sort
  48.                                         (K:GetSSBoxLst SS);嵌套表,每个图元坐标一个子表,(左(minX) 下(miny) 右(maxx) 上(maxy))
  49.                                         '(lambda (A B) ;左下右上
  50.                                                  (if (equal (car A) (car B) 1e-3)
  51.                                                          (if (equal (cadr A) (cadr B) 1e-3)
  52.                                                                  (if (equal (caddr A) (caddr B) 1e-3)
  53.                                                                          (< (cadddr A) (cadddr B)) ;上小在前
  54.                                                                          (< (caddr A) (caddr B)) ;右小在前
  55.                                                                  )
  56.                                                                  (< (cadr A) (cadr B)) ;下小在前
  57.                                                          )
  58.                                                          (< (car A) (car B)) ;左小在前
  59.                                                  )
  60.                                          )
  61.                                 )
  62.       );边界框矩形排序,左小->下小->右小->上小,即从左往右,从下往上排序
  63.       (setq Lst
  64.                                 (mapcar
  65.                                         '(lambda (x)
  66.                                                  (list
  67.                                                          (- (car x) Dist)
  68.                                                          (- (cadr x) Dist)
  69.                                                          (+ (caddr x) Dist)
  70.                                                          (+ (cadddr x) Dist)
  71.                                                  )
  72.                                          )
  73.                                         Lst
  74.                                 )
  75.       );矩形扩大
  76.                         (setq Flag T
  77.                                 NewLst Nil
  78.                         )
  79.                         (while Flag
  80.                                 (setq BasRec (car Lst);第一个元素
  81.                                         TmpLst Nil
  82.                                 )
  83.                                 (repeat (1-(length Lst))
  84.                                         (setq lst (cdr lst))
  85.                                         (if (setq IntRec (K:2RecIntersect BasRec (setq FstRec (car Lst)))) ;如果相交,新表
  86.                                                 (setq BasRec IntRec);更新表
  87.                                                 (setq TmpLst (cons FstRec TmpLst))
  88.                                         )
  89.                                 )
  90.                                 (setq NewLst (cons BasRec NewLst)
  91.                                         lst (reverse TmpLst)
  92.                                 )
  93.                                 (if (null TmpLst)
  94.                                         (setq Flag Nil)
  95.                                 )
  96.       )
  97.       (setq Lst
  98.                                 (mapcar
  99.                                         '(lambda (x)
  100.                                                  (list
  101.                                                          (+ (car x) Dist)
  102.                                                          (+ (cadr x) Dist)
  103.                                                          (- (caddr x) Dist)
  104.                                                          (- (cadddr x) Dist)
  105.                                                  )
  106.                                          )
  107.                                         NewLst
  108.                                 )
  109.       );矩形缩小
  110.                 )
  111.   );矩形分堆得到互不相交的矩形LST
  112.   (setq Lst
  113.                 (mapcar
  114.                         '(lambda (x)
  115.                                  (list
  116.                                          (list (car x) (cadr x))
  117.                                          (list (caddr x) (cadddr x))
  118.                                  )
  119.                          )
  120.                         Lst
  121.                 )
  122.         );调整LST表的数据结构
  123. )
发表于 2024-6-8 12:30:26 | 显示全部楼层
另外,我觉得vl-sort排序函数,用cond编写条件是不是好一点,用if条理没有cond清晰。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-9-8 09:29 , Processed in 0.314414 second(s), 17 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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