明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
123
返回列表 发新帖
楼主: 669423907

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

[复制链接]
发表于 2019-9-29 20:33 | 显示全部楼层

点评

谢谢提供好资料  发表于 2019-9-30 13:52
回复

使用道具 举报

 楼主| 发表于 2019-9-30 13:51 | 显示全部楼层
wyl219 发表于 2019-9-15 22:43
能实现功能,按空格退出命令,按esc也能退出,但是不会取消亮显,可以参考一下.

非常感谢wyl219大师的热情帮助,程序很好,我试着改一下
回复

使用道具 举报

发表于 2019-9-30 17:02 | 显示全部楼层
人家的矩形是可以只有部分在屏幕范围内,那样就矩形内屏幕上一点任意方向都能选到这个矩形的了。。。
回复

使用道具 举报

 楼主| 发表于 2019-9-30 21:12 | 显示全部楼层
llsheng_73 发表于 2019-9-30 17:02
人家的矩形是可以只有部分在屏幕范围内,那样就矩形内屏幕上一点任意方向都能选到这个矩形的了。。。

是呃,我还没注意到
回复

使用道具 举报

 楼主| 发表于 2019-9-30 21:15 | 显示全部楼层
wyl219 发表于 2019-9-15 22:43
能实现功能,按空格退出命令,按esc也能退出,但是不会取消亮显,可以参考一下.

忘了要适应不完全在屏幕上的矩形,方便改一下吗?
回复

使用道具 举报

发表于 2019-10-5 15:01 | 显示全部楼层
669423907 发表于 2019-9-30 21:15
忘了要适应不完全在屏幕上的矩形,方便改一下吗?

我也是刚知道原来不在屏幕上的图形用栏选选不到.
当然可以实现,通过上下左右获取四个选择集,然后将其合并,就能得到点四周所有的多段线对象,然后利用黄老师的两个函数判断点是否在多段线内.通过这个方式获取选择集,能解决不完全在屏幕上的矩形,但是不能解决完全不在屏幕上的矩形.
如果想要选完全不在屏幕上的图形,应该可以用ssget "x"全选所有的多段线,然后按原方式筛选,不过这样太慢了,不知道有没有别的好办法.
  1. ;|
  2. 说明:根据鼠标位置亮显离自己最近的封闭四边形,用esc退出命令,建议修改error函数,当esc退出命令时关闭亮显.
  3. v2:可以亮显不完全在屏幕内的矩形
  4. |;
  5. (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 en  en_selold en_sel lst_pttoobj_dist obj bo lst_ss_sel ss_sel )
  6. ;(defun c:ttt ( /  )
  7.   (vl-load-com)
  8.   (setq old_error *error*)  
  9.   ;(setq *error* wyl:err) ;可以修改为自己的error函数
  10.   ;start部分结束
  11.   (setq fill (list '(0 . "LWPOLYLINE") '(70 . 1)));筛选条件为闭合的多段线
  12.   (setq bo t)
  13.   (while bo
  14.     (if (= (car (setq pt_tmp (grread t 1 ))) 5);当获取到的为坐标点时
  15.       ;(setq pt_tmp (getpoint));debug
  16.       (progn
  17.         (setq pt_tmp (cadr pt_tmp))
  18.         (setq pt_x1 (list  (car pt_tmp) (expt 10 9) 0.0)
  19.           pt_x2 (list (car pt_tmp) (expt -10 9) 0.0)
  20.           pt_y1 (list   (expt 10 9) (cadr pt_tmp) 0.0)
  21.           pt_y2 (list  (expt -10 9) (cadr pt_tmp) 0.0)
  22.         )
  23.         (setq ss_x1 (ssget "F" (list pt_x1 pt_tmp) fill)
  24.           ss_x2 (ssget "F" (list pt_x2 pt_tmp) fill)
  25.           ss_y1 (ssget "F" (list pt_y1 pt_tmp) fill)
  26.           ss_y2 (ssget "F" (list pt_y2 pt_tmp) fill)
  27.         );获取四个方向的闭合多段线
  28.         (setq ss_sel (wyl:joinss "" (list ss_x1 ss_x2 ss_y1 ss_y2)));建立一个新的选择集,存储上面所有的选择集的内容
  29.         (setq ss_x1 nil
  30.           ss_x2 nil
  31.           ss_y1 nil
  32.           ss_y2 nil
  33.         )
  34.         (if (and ss_sel (>  (sslength ss_sel) 0));如果选择集不为空
  35.           (progn
  36.             (setq ss_new (ssadd));新建一个选择集
  37.             (setq lst_ss_sel (wyl:ss2ptlist ss_sel -1 ));把选择集变成列表,方便使用foreach
  38.             (setq en1 (nth 0 lst_ss_sel))
  39.             (foreach en1 lst_ss_sel
  40.               (if (PtInorOut1 (HH:PtLists en1) pt_tmp);如果点在多段线内
  41.                 (ssadd en1 ss_new)
  42.               );endif
  43.             );endforeach
  44.             (setq ss_sel nil)
  45.             (cond
  46.               ((= 1 (sslength ss_new));如果只有一个候选项
  47.                 (progn
  48.                   (setq en_selold en_sel);备份一下上次亮显的对象
  49.                   (if (and (setq en_sel (ssname  ss_new 0 ))
  50.                         (= (vl-princ-to-string en_selold) (vl-princ-to-string en_sel))  );如果两次获取到的对象相同,那么
  51.                     (redraw  en_sel  3);直接将他亮显
  52.                     (progn ;else
  53.                       (redraw  en_sel  3)
  54.                       (if  en_selold (redraw  en_selold  4));取消原来的亮显
  55.                     )
  56.                   );endif
  57.                 ))
  58.               ((>  (sslength ss_new) 1);如果不止一个
  59.                 (setq lst_pttoobj_dist nil)
  60.                 (repeat (setq i (sslength ss_new));判断距离
  61.                   (setq i (1- i)
  62.                     en (ssname  ss_new i)
  63.                     obj (vlax-ename->vla-object en)
  64.                   )
  65.                   (setq lst_pttoobj_dist (append (list (list (distance (vlax-curve-getClosestPointTo obj pt_tmp) pt_tmp) en)) '() lst_pttoobj_dist))
  66.                 );endrepeat
  67.                 (setq lst_pttoobj_dist (vl-sort lst_pttoobj_dist '(lambda (x y) (< (car x) (car y)))) );对距离排序
  68.                 (setq en_selold en_sel);备份一下上次亮显的对象
  69.                 (if (and ;lst_pttoobj_dist
  70.                       (setq en_sel (cadr (nth 0 lst_pttoobj_dist) ))
  71.                       (= (vl-princ-to-string en_selold) (vl-princ-to-string en_sel));直接判断是不相等的
  72.                     );如果两次获取到的对象相同,那么
  73.                   (redraw  en_sel  3);将他亮显
  74.                   (progn ;else
  75.                     (redraw  en_sel  3)
  76.                     (if en_selold (redraw  en_selold  4));取消原来的亮显
  77.                   )
  78.                 );endif
  79.               );end progn
  80.             );endcond
  81.           ));end if
  82.       );end progn
  83.     );endif
  84.     (if  (equal (grread t 1 ) '(2 32)) ;如果输入空格
  85.       (progn
  86.         (if en_sel (redraw  en_sel  4));取消对象亮显
  87.         (setq bo nil));结束循环
  88.     )
  89.   );endwhile
  90.   ;end部分开始
  91.   (setvar "cmdecho" 1)
  92.   (setq *error* old_error)  
  93. )
  94. ;;164.40 [功能] 点在封闭多段线内返回T,其余nil  By 狂刀(见175)
  95. ;;本程序为狂刀思想,并非源程序
  96. ;;(PtInorOut1 ((HH:PtLists (car(entsel))) (getpoint))
  97. (defun PtInorOut1 (pts pt / P1 P2 PI)
  98.   (setq PI 3.14159);不知道cad本身有没有这个常量
  99.   (setq pts (MAPCAR '(LAMBDA (p1 p2) (REM (- (ANGLE pt p1) (ANGLE pt p2)) PI))
  100.               (CONS (LAST pts) pts)
  101.               pts
  102.             )
  103.   )
  104.   ; (equal (ABS (APPLY '+ pts)) PI ) ;原来的语句不含容错,所以可能会出错
  105.   (equal (ABS (APPLY '+ pts)) PI  0.00001)
  106. )
  107. ;;164.3 [功能] 多段线端点列表
  108. ;;示例(HH:PtLists (car (entsel)))
  109. (defun HH:PtLists (en)
  110.   (mapcar 'cdr
  111.     (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget en))
  112.   )
  113. )
  114. ;;选择集转为dxf列表
  115. ;;说明:传入选择集,将对应的组码返回
  116. ;;参数:ss:选择集
  117. ;;参数:dxf:组码,例如10代表插入点,0代表对象类型,2代表对象名,8代表图层,-1是图元名
  118. ;;返回:列表
  119. (defun wyl:ss2ptlist ( ss dxf / n i elist )
  120.   ;(defun ss2ptlist ( ss / )
  121.   (setq n (if (= (type ss) 'Pickset) (sslength ss) 0)
  122.     elist '()
  123.   )
  124.   (repeat n
  125.     (setq elist (cons  (cdr (assoc dxf  (entget (ssname ss (setq n (1- n))))))  elist))
  126.   )
  127. )
  128. ;|
  129. 说明:将多个选择集合并后返回,选择集可以为空
  130. 参数:ss要被合并进去的选择集,可以用""占位.
  131. lstss,多个选择集组成的列表
  132. 返回值:合并后的选择集
  133. |;
  134. (defun wyl:joinss( ss lst_ss / )
  135.   (if (or (not ss ) (= "" ss))
  136.     (setq ss (ssadd)))
  137.   (foreach ss1 lst_ss
  138.     (if ss1 ;如果选择集不为空
  139.       (progn
  140.         (repeat (setq i (sslength ss1))
  141.           (setq i (1- i))
  142.           (ssadd (ssname ss1 i) ss)
  143.         );endrepeat
  144.       );endprogn
  145.     );endif
  146.   );end foreach
  147.   ss
  148. )
  149. (princ "加载成功,命令名ttt")
  150. (princ)


回复

使用道具 举报

 楼主| 发表于 2019-10-10 08:22 | 显示全部楼层
wyl219 发表于 2019-10-5 15:01
我也是刚知道原来不在屏幕上的图形用栏选选不到.
当然可以实现,通过上下左右获取四个选择集,然后将其合 ...

再次非常感谢wyl219大师的热情帮助
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-3 06:51 , Processed in 0.306416 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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