【讨论】:求选择集左下角点的最快的方法(已附3种源码和测试图形及时间)
本帖最后由 sfzyr 于 2012-5-12 12:24 编辑选择一堆图形,自动求得其“左下角” 经常在实用程序中用到,比如自动坐标标注 (三个视图默认左下角为坐标的0点),这是就要用到,今天写一个 模拟 :"ctrl +shift +v”建立一个图块,(也以左下角为基点,但是以“图层名+视图位置编号”为块名) 可是人家的ctrl +shift +v就是速度快,几万个数据点,也看不出假死现象,我写了三种方法,速度都慢,现把三种方法贴上,希望大家讨论,并给出最好的程序,最快求得“左下角” 坐标??
注:选择对象不含 "CENTER""ARC" "HATCH" "TEXT" "MTEXT" "ATTDEF"
法一:求点集list,对点表 按 x排序,取最小x ,对电表按照 y排序取 最小y ,最终求得 左下角(x y)
(defun data_num (xx lstSel_xx / data_xx)
(setq data_xx nil)
(setq lstSel_xx (member (assoc xx lstSel_xx) lstSel_xx))
(while lstSel_xx
(setq data_xx (cons (cdr (car lstSel_xx)) data_xx))
(setq
lstSel_xx (member (assoc xx (cdr lstSel_xx)) (cdr lstSel_xx))
)
)
data_xx
)
(defun sub_getdata
(objSel /data data10 data11
ssIndex objLen objCur lstSel objtype
entCur
)
(vl-load-com)
(setq data nil)
(setq ssIndex 0)
(setq objLen (sslength objSel))
(repeat objLen
(setq objCur (ssname objSel ssIndex))
(setq lstSel (entget objCur))
(setq objtype (cdr (assoc '6 lstSel)))
(setq entCur (cdr (assoc '0 lstSel)))
(if (and (/= objtype "CENTER")
(/= entCur "ARC")
(/= entCur "HATCH")
(/= entCur "TEXT")
(/= entCur "MTEXT")
(/= entcur "ATTDEF")
)
(progn
(setq data10 (data_num 10 lstsel))
(setq data11 (data_num 11 lstsel))
(setq data (append (append data10 data11) data))
)
)
(setq ssIndex (+ ssIndex 1))
)
(setq data (vl-remove nil data))
)
;;;====================================================================
(defun sub_minx (data_xsrt / datax e1 e2 minx)
(vl-load-com)
(setq datax
(vl-sort data_xsrt
(function (lambda (e1 e2) (< (car e1) (car e2))))
)
)
(setq minx (car (car datax)))
)
;;;====================================================================
(defun sub_miny (data_ysrt / datay e3 e4 miny)
(vl-load-com)
(setq datay
(vl-sort data_ysrt
(function (lambda (e3 e4) (< (cadr e3) (cadr e4))))
)
)
(setq miny (cadr (car datay)))
)
(defun c:t1
(/ oldOsm oldCmdecho selset t0 ssdata ssminx ssminy wd_bpnt)
(setq oldOsm (getvar "OSMODE"))
(setq oldCmdecho (getvar "CMDECHO"))
(setvar "OSMODE" 0)
(setvar "CMDECHO" 0)
(setq selset (ssget))
(if selset
(progn
(setq t0 (getvar "TDUSRTIMER"))
(setq ssdata (sub_getdata selset))
(setq ssminx (sub_minx ssdata))
(setq ssminy (sub_miny ssdata))
(setq wd_bpnt (list ssminx ssminy))
(princ (* (- (getvar "TDUSRTIMER") t0) 86400))
(princ "秒,最小x,y是:")
wd_bpnt
)
)
)
法二:用vla-GetBoundingBox 求点表 在对点表求最小(x y)
(defun get_all_rectang (/ ss pt_list sn n en pt1 pt2)
(setq ss (ssget "p"
'((-4 . "<not")
(0 . "LEADER,CENTER,ARC,HATCH,TEXT,MTEXT,ATTDEF")
(-4 . "not>")
)
)
)
(setq pt_list '())
(setq sn (sslength ss))
(setq n -1)
(repeat sn
(setq en (ssname ss (setq n (1+ n))))
(vla-GetBoundingBox (vlax-ename->vla-object en) 'pt1 'pt2)
(setq pt_list (cons (vlax-safearray->list pt1) pt_list))
;;(setq pt_list (cons (vlax-safearray->list pt2) pt_list))
)
(setq pt1 (apply 'mapcar (cons 'min pt_list)))
)
(defun c:t2
(/ oldOsm oldCmdecho selset t0 wd_bpnt)
(setq oldOsm (getvar "OSMODE"))
(setq oldCmdecho (getvar "CMDECHO"))
(setvar "OSMODE" 0)
(setvar "CMDECHO" 0)
(setq selset (ssget))
(if selset
(progn
(setq t0 (getvar "TDUSRTIMER"))
(setq wd_bpnt (get_all_rectang))
(princ (* (- (getvar "TDUSRTIMER") t0) 86400))
(princ "秒,最小x,y是:")
wd_bpnt
)
)
)
法三:用 ET工具里求极限点的函数 (ACET-GEOM-SS-EXTENTS SS t)
(defun c:t3 (/ oldOsm oldCmdecho selset t0 wd_bpnt)
(setq oldOsm (getvar "OSMODE"))
(setq oldCmdecho (getvar "CMDECHO"))
(setvar "OSMODE" 0)
(setvar "CMDECHO" 0)
(setq selset (ssget))
(if selset
(progn
(setq t0 (getvar "TDUSRTIMER"))
(setq
ss (ssget "p"
'((-4 . "<not")
(0 . "LEADER,CENTER,ARC,HATCH,TEXT,MTEXT,ATTDEF")
(-4 . "not>")
)
)
)
(setq wd_bpnt (car (ACET-GEOM-SS-EXTENTS SS t)))
(princ (* (- (getvar "TDUSRTIMER") t0) 86400))
(princ "秒,最小x,y是:")
wd_bpnt
)
)
)
对下图运算后:
时间如下:
命令: t1
选择对象: 指定对角点: 找到 14400 个
选择对象:
44.235秒,最小x,y是:(-384.388 -172.718)
命令:
命令: t2
选择对象: 指定对角点: 找到 14400 个
选择对象:
1.672秒,最小x,y是:(-384.388 -172.718 0.0)
命令:
命令: t3
选择对象: 指定对角点: 找到 14400 个
选择对象:
4.156秒,最小x,y是:(-384.388 -172.718 0.0)
命令
本帖最后由 sfzyr 于 2012-5-11 23:01 编辑
其中对et函数(ACET-GEOM-SS-EXTENTS SS t)
不解,内部不知道什么算法。用时居然超过 t2 方法
注明:不知道各位运算时间怎样,与配置是否有关 我电脑的配置
电脑型号 技嘉 GA-880G-UD3H 台式电脑
操作系统 Windows XP 专业版 32位 SP3 ( DirectX 9.0c )
处理器 AMD Athlon(速龙) II X4 640 四核
主板 技嘉 GA-880G-UD3H (AMD 760G/780G/780V/785G/790GX/880G/890GX)
内存 2 GB ( 金士顿 DDR3 1333MHz )
主硬盘 希捷 ST31000524AS ( 1 TB / 7200 转/分 )
显卡 ATI Radeon HD 5600/5700( 512 MB / HIS )
望各位版主,各位高手给出个优化算法,谢谢!! 本帖最后由 sfzyr 于 2012-5-11 22:59 编辑
第一次发有代码的帖子,希望给予支持,得到满意答案,谢谢!
为什么 “ctrl + shift + v” 马上就算出了左下角??不解
这贴要得,学习了 顶一下 T3出错 命令: T3
选择对象: 指定对角点: 找到 11 个
选择对象:; 错误: no function definition: ACET-GEOM-SS-EXTENTS t1t2 有圆弧的没把圆弧也计算进去 圆的话算的是圆心……期待完善
页:
[1]