669423907 发表于 2019-9-15 22:43:41

如何自动选中并亮显包围光标点的矩形?

如何自动选中并亮显特定的矩形
1:此矩形所在的图层为0层
2:光标点(setq o (cadr(grread 3)))刚好在此矩形内
3:此矩形可能不完全在屏幕内
4:此矩形距离o最近(可能矩形外还有更大的矩形)






wyl219 发表于 2019-9-15 22:43:42

本帖最后由 wyl219 于 2019-9-29 22:59 编辑

能实现功能,按空格退出命令,按esc也能退出,但是不会取消亮显,可以参考一下.

(defun c:ttt ( / wyl:err old_error fill pt_tmp pt_x1 pt_x2 pt_y1 pt_y2 ss_x1 ss_x2 ss_y1 ss_y2
               ss_new i enen_selold en_sel lst_pttoobj_dist obj bo )
(vl-load-com)
(setq old_error *error*)
(setq *error* wyl:err) ;可以修改为自己的error函数
;start部分结束
(setq fill (list '(0 . "LWPOLYLINE") '(70 . 1)));筛选条件为闭合的多段线
(setq bo t)
(while bo
    (if (= (car (setq pt_tmp (grread t 1 ))) 5);当获取到的为坐标点时
      (progn
      (setq pt_tmp (cadr pt_tmp))
      (setq pt_x1 (list(car pt_tmp) (expt 10 9) 0.0)
          pt_x2 (list (car pt_tmp) (expt -10 9) 0.0)
          pt_y1 (list   (expt 10 9) (cadr pt_tmp) 0.0)
          pt_y2 (list(expt -10 9) (cadr pt_tmp) 0.0)
      )
      (setq ss_x1 (ssget "F" (list pt_x1 pt_tmp) fill)
          ss_x2 (ssget "F" (list pt_x2 pt_tmp) fill)
          ss_y1 (ssget "F" (list pt_y1 pt_tmp) fill)
          ss_y2 (ssget "F" (list pt_y2 pt_tmp) fill)
      );获取四个方向的闭合多段线
      (if (and ss_x1
            ss_x2
            ss_y1
            ss_y2);如果四个选择集都不为空
          (progn
            (setq ss_new (ssadd));新建一个选择集
            (repeat (setq i (sslength ss_x1));因为目标矩形同时在四个选择集中,任意选一个就行.
            (setq i (1- i)
                en (ssnamess_x1 i)
            )
            (if (and (ssmemb en ss_x2) (ssmemb en ss_y1) (ssmemb en ss_y2);如果同时在四个选择集
                  (= 8 (length (Vlax-Get (Vlax-Ename->Vla-Object en) 'Coordinates)))
                  );并且有四个顶点,这个可以省略,适配所有封闭多段线
                (ssadd en ss_new);加入到新选择集
            );endif
            );endrepeat
            (cond
            ((= 1 (sslength ss_new));如果只有一个候选项
                (progn
                  (setq en_selold en_sel);备份一下上次亮显的对象
                  (if (and (setq en_sel (ssnamess_new 0 ))
                        (= (vl-princ-to-string en_selold) (vl-princ-to-string en_sel)));如果两次获取到的对象相同,那么
                  (redrawen_sel3);直接将他亮显
                  (progn ;else
                      (redrawen_sel3)
                      (ifen_selold (redrawen_selold4));取消原来的亮显
                  )
                  );endif
                ))
            ((>(sslength ss_new) 1);如果不止一个
                (setq lst_pttoobj_dist nil)
                (repeat (setq i (sslength ss_new));判断距离
                  (setq i (1- i)
                  en (ssnamess_x1 i)
                  obj (vlax-ename->vla-object en)
                  )
                  (setq lst_pttoobj_dist (append (list (list (distance (vlax-curve-getClosestPointTo obj pt_tmp) pt_tmp) en)) '() lst_pttoobj_dist))
                );endrepeat
                (setq lst_pttoobj_dist (vl-sort lst_pttoobj_dist '(lambda (x y) (< (car x) (car y)))) );对距离排序
                (setq en_selold en_sel);备份一下上次亮显的对象
                (if (and ;lst_pttoobj_dist
                      (setq en_sel (cadr (nth 0 lst_pttoobj_dist) ))
                      (= (vl-princ-to-string en_selold) (vl-princ-to-string en_sel));直接判断是不相等的
                  );如果两次获取到的对象相同,那么
                  (redrawen_sel3);将他亮显
                  (progn ;else
                  (redrawen_sel3)
                  (if en_selold (redrawen_selold4));取消原来的亮显
                  )
                );endif
            );end progn
            );endcond
          ));end if
      );end progn
    );endif
    (if(equal (grread t 1 ) '(2 32)) ;如果输入空格
      (progn
      (if en_sel (redrawen_sel4));取消对象亮显
      (setq bo nil));结束循环
    )
);endwhile
;end部分开始
(setvar "cmdecho" 1)
(setq *error* old_error)
)
(princ)


菜卷鱼 发表于 2019-9-16 08:31:10

可以采用ssget 里面的栏选功能

669423907 发表于 2019-9-16 09:07:22

菜卷鱼 发表于 2019-9-16 08:31
可以采用ssget 里面的栏选功能

不是啊,我要的是不用手动去选,让程序自动根据o点自动选中矩形

菜卷鱼 发表于 2019-9-16 09:24:57

669423907 发表于 2019-9-16 09:07
不是啊,我要的是不用手动去选,让程序自动根据o点自动选中矩形

你不是grread得到了一个点吗?再通过这个点,再多算几个点pt1、2、3、4,
然后再(ssget "f" <pt-list> ),不需要手动啊。
最后再提示你一下(getvar "viewsize") 是得到屏幕的比例,你应该可以算出光标的上下左右4个点

669423907 发表于 2019-9-16 09:32:33

菜卷鱼 发表于 2019-9-16 09:24
你不是grread得到了一个点吗?再通过这个点,再多算几个点pt1、2、3、4,
然后再(ssget "f"

你看一下我第2和第4点的要求

菜卷鱼 发表于 2019-9-16 11:38:19

669423907 发表于 2019-9-16 09:32
你看一下我第2和第4点的要求

你自己去试一下吧,水平这么菜脾气还这么臭,还不敢于尝试

(defun c:tt (/ o s pt1 pt2 pt3 pt4 ss1 ss2)
(setq o (cadr(grread 3)))
(setq s(getvar "viewsize"))
(setq pt1 (polar o 0 s))
(setq pt2 (polar o (* 0.5 pi) s))
(setq pt3 (polar o pi s))
(setq pt4 (polar o (* 1.5 pi) s))
(setq ss1 (ssget "f" (list pt1 pt3) '((0 ."LWPOLYLINE" )(8 . "0"))))
(setq ss2 (ssget "f" (list pt2 pt4) '((0 ."LWPOLYLINE" )(8 . "0"))))
(command "select" ss1 ss2)
(prin1)
)

xyp1964 发表于 2019-9-16 11:50:19


669423907 发表于 2019-9-16 12:00:39

菜卷鱼 发表于 2019-9-16 11:38
你自己去试一下吧,水平这么菜脾气还这么臭,还不敢于尝试

大哥,别误会哈,我脾气很好的,只是文字上表达欠佳,我是卡在第4点上了

669423907 发表于 2019-9-16 12:03:06

xyp1964 发表于 2019-9-16 11:50


院长是个传奇人物,厉害
页: [1] 2 3
查看完整版本: 如何自动选中并亮显包围光标点的矩形?