明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
12
返回列表 发新帖
楼主: 林小林子

[源码] 动态加矩形

[复制链接]
 楼主| 发表于 2025-12-4 10:50:21 | 显示全部楼层
本帖最后由 林小林子 于 2025-12-7 10:37 编辑
oysheji 发表于 2025-11-17 17:35
为什么偏移的距离带小数点呢
  1. ;;动态框绘制 By 明经通道 Gu_xl 修改版 - 增强版
  2. (defun c:DD (/ GetScreenCoords gr lmts loop pt s1 s2 s3 s4 p1 p2 p3 p4 ll ru lu rl
  3.                dist thickness move_dist direction ent_old input new_thick)
  4.   ;;定义全局变量存储板厚和移动距离
  5.   (if (not *thickness*)
  6.     (setq *thickness* 18.0)  ;;默认板厚为18
  7.   )
  8.   (if (not *move-distance*)
  9.     (setq *move-distance* 0.0)  ;;默认移动距离为0
  10.   )
  11.   
  12.   ;;设置默认值
  13.   (setq thickness *thickness*)
  14.   (setq move_dist *move-distance*)
  15.   
  16.   ;;取得当前绘图区屏幕的左下角和右上角的坐标
  17.   (defun GetScreenCoords (/ c03 c08 c04 c05 c07 c06 c09 c01 c02)
  18.     (setq c03 (getvar "viewctr")
  19.           c03 (trans c03 1 2)
  20.           c08 (getvar "viewsize")
  21.           c04 (getvar "screensize")
  22.           c07 (car c04)
  23.           c06 (cadr c04)
  24.           c09 (/ (* c08 c07) c06)
  25.           c01 (list (- (car c03) (* 0.5 c09)) (- (cadr c03) (* 0.5 c08)))
  26.           c02 (list (+ (car c03) (* 0.5 c09)) (+ (cadr c03) (* 0.5 c08)))
  27.           c01 (trans c01 2 1)
  28.           c02 (trans c02 2 1)
  29.     )
  30.     (list c01 c02)
  31.   )
  32.   
  33.   (princ (strcat "\n当前设置: 板厚=" (rtos thickness 2 2) " 距离=" (rtos move_dist 2 2) " (按S修改设置)"))
  34.   
  35.   (setq loop t)
  36.   (while loop
  37.     (setq lmts (GetScreenCoords))
  38.     (setq gr (grread t 15 0))
  39.     (cond
  40.       ((= 5 (car gr))  ;;鼠标移动
  41.         (setq pt (cadr gr))
  42.         (if (and
  43.               (setq s1 (ssget "F"
  44.                               (list pt (list (car pt) (cadadr lmts) 0))
  45.                               '((0 . "*line,arc,circle"))
  46.                        )
  47.               ) ;_ 向上
  48.               (setq s2 (ssget "F"
  49.                               (list pt (list (car pt) (cadar lmts) 0))
  50.                               '((0 . "*line,arc,circle"))
  51.                        )
  52.               ) ;_ 向下
  53.               (setq s3 (ssget "F"
  54.                               (list pt (list (caar lmts) (cadr pt) 0))
  55.                               '((0 . "*line,arc,circle"))
  56.                        )
  57.               ) ;_ 向左
  58.               (setq s4 (ssget "F"
  59.                               (list pt (list (caadr lmts) (cadr pt) 0))
  60.                               '((0 . "*line,arc,circle"))
  61.                        )
  62.               ) ;_ 向右
  63.             )
  64.           (progn
  65.             (setq p1 (trans (cadar (cdddar (ssnamex s1))) 0 1)) ;_ 上点
  66.             (setq p2 (trans (cadar (cdddar (ssnamex s2))) 0 1)) ;_ 下点
  67.             (setq p3 (trans (cadar (cdddar (ssnamex s3))) 0 1)) ;_ 左点
  68.             (setq p4 (trans (cadar (cdddar (ssnamex s4))) 0 1)) ;_ 右点
  69.             (setq ll (apply 'mapcar (cons 'min (list p1 p2 p3 p4)))) ;_ 左下角点
  70.             (setq ru (apply 'mapcar (cons 'max (list p1 p2 p3 p4)))) ;_ 右上角点
  71.             (setq lu (list (car ll) (cadr ru) 0)) ;_ 左上角点
  72.             (setq rl (list (car ru) (cadr ll) 0)) ;_ 右下角点
  73.             
  74.             ;;判断鼠标在矩形内部的位置
  75.             (setq direction (GetMouseDirection pt ll ru))
  76.             
  77.             (redraw)
  78.             ;;绘制原始矩形
  79.             (grdraw ll lu 1)
  80.             (grdraw lu ru 1)
  81.             (grdraw ru rl 1)
  82.             (grdraw rl ll 1)
  83.             
  84.             ;;根据鼠标位置绘制偏移矩形
  85.             (DrawOffsetRect ll ru direction thickness move_dist)
  86.           )
  87.           (redraw)
  88.         )
  89.       )
  90.       ((= 3 (car gr))  ;;鼠标左键点击
  91.         (setq loop nil)
  92.         (if (and ll ru direction)
  93.           (progn
  94.             ;;创建偏移矩形
  95.             (CreateOffsetRect ll ru direction thickness move_dist)
  96.           )
  97.           (command "_.rectang")
  98.         )
  99.       )
  100.       ((= 2 (car gr))  ;;键盘输入
  101.         (cond
  102.           ((= (cadr gr) 27)  ;;ESC键退出
  103.             (setq loop nil)
  104.           )
  105.           ((or (= (cadr gr) 83) (= (cadr gr) 115))  ;;S键 - 修改设置
  106.             ;;获取板厚输入
  107.             (initget 6) ; 禁止负数和0
  108.             (setq new_thick (getreal (strcat "\n请输入板厚 <" (rtos *thickness* 2 2) ">: ")))
  109.             (if new_thick
  110.               (setq *thickness* new_thick thickness new_thick)
  111.             )
  112.             
  113.             ;;获取移动距离输入 - 修改为允许0在内的正数值
  114.             (initget 4) ; 允许0和正数,禁止负数
  115.             (setq move_dist (getreal (strcat "\n请输入移动距离 <" (rtos *move-distance* 2 2) ">: ")))
  116.             (if move_dist
  117.               (setq *move-distance* move_dist)
  118.               (setq move_dist *move-distance*)
  119.             )
  120.             
  121.             (princ (strcat "\n当前设置: 板厚=" (rtos thickness 2 2) " 距离=" (rtos move_dist 2 2) " (按S修改设置)"))
  122.           )
  123.         )
  124.       )
  125.     )
  126.   )
  127.   (redraw)
  128.   (princ)
  129. )

  130. ;;判断鼠标在矩形内部的位置
  131. (defun GetMouseDirection (pt ll ru / center relX relY)
  132.   (setq center (list (/ (+ (car ll) (car ru)) 2.0)
  133.                      (/ (+ (cadr ll) (cadr ru)) 2.0)
  134.                      (caddr ll)))
  135.   
  136.   ;;计算相对位置
  137.   (setq relX (- (car pt) (car center))
  138.         relY (- (cadr pt) (cadr center)))
  139.   
  140.   ;;根据相对位置判断方向
  141.   (cond
  142.     ((and (> (abs relY) (abs relX)) (> relY 0)) "top")     ;;上部
  143.     ((and (> (abs relY) (abs relX)) (< relY 0)) "bottom")  ;;下部
  144.     ((and (> (abs relX) (abs relY)) (> relX 0)) "right")   ;;右侧
  145.     ((and (> (abs relX) (abs relY)) (< relX 0)) "left")    ;;左侧
  146.     (t "top")  ;;默认上部
  147.   )
  148. )

  149. ;;绘制偏移矩形
  150. (defun DrawOffsetRect (ll ru direction thickness move_dist / newLL newRU newLU newRL)
  151.   (cond
  152.     ((= direction "top")    ;;上部矩形 - 向下移动
  153.       (setq newLL (list (car ll) (- (- (cadr ru) thickness) move_dist) 0)
  154.             newRU (list (car ru) (- (cadr ru) move_dist) 0))
  155.     )
  156.     ((= direction "bottom") ;;下部矩形 - 向上移动
  157.       (setq newLL (list (car ll) (+ (cadr ll) move_dist) 0)
  158.             newRU (list (car ru) (+ (+ (cadr ll) thickness) move_dist) 0))
  159.     )
  160.     ((= direction "left")   ;;左侧矩形 - 向右移动
  161.       (setq newLL (list (+ (car ll) move_dist) (cadr ll) 0)
  162.             newRU (list (+ (+ (car ll) thickness) move_dist) (cadr ru) 0))
  163.     )
  164.     ((= direction "right")  ;;右侧矩形 - 向左移动
  165.       (setq newLL (list (- (- (car ru) thickness) move_dist) (cadr ll) 0)
  166.             newRU (list (- (car ru) move_dist) (cadr ru) 0))
  167.     )
  168.   )
  169.   
  170.   (setq newLU (list (car newLL) (cadr newRU) 0)
  171.         newRL (list (car newRU) (cadr newLL) 0))
  172.   
  173.   ;;绘制偏移矩形(用不同颜色显示,比如绿色)
  174.   (grdraw newLL newLU 3)
  175.   (grdraw newLU newRU 3)
  176.   (grdraw newRU newRL 3)
  177.   (grdraw newRL newLL 3)
  178. )

  179. ;;创建偏移矩形
  180. (defun CreateOffsetRect (ll ru direction thickness move_dist / newLL newRU)
  181.   (cond
  182.     ((= direction "top")    ;;上部矩形 - 向下移动
  183.       (setq newLL (list (car ll) (- (- (cadr ru) thickness) move_dist) 0)
  184.             newRU (list (car ru) (- (cadr ru) move_dist) 0))
  185.     )
  186.     ((= direction "bottom") ;;下部矩形 - 向上移动
  187.       (setq newLL (list (car ll) (+ (cadr ll) move_dist) 0)
  188.             newRU (list (car ru) (+ (+ (cadr ll) thickness) move_dist) 0))
  189.     )
  190.     ((= direction "left")   ;;左侧矩形 - 向右移动
  191.       (setq newLL (list (+ (car ll) move_dist) (cadr ll) 0)
  192.             newRU (list (+ (+ (car ll) thickness) move_dist) (cadr ru) 0))
  193.     )
  194.     ((= direction "right")  ;;右侧矩形 - 向左移动
  195.       (setq newLL (list (- (- (car ru) thickness) move_dist) (cadr ll) 0)
  196.             newRU (list (- (car ru) move_dist) (cadr ru) 0))
  197.     )
  198.   )
  199.   
  200.   (command "_.rectang" "_non" newLL "_non" newRU)
  201. )

  202. ;;删除识别内空的矩形
  203. (defun c:DeleteInnerRects (/ ss i ent obj minpt maxpt bounds allrects outer inner todelete)
  204.   (princ "\n选择要清理的矩形集合: ")
  205.   (setq ss (ssget '((0 . "LWPOLYLINE") (90 . 4))))  ; 选择多段线矩形
  206.   
  207.   (if ss
  208.     (progn
  209.       (setq allrects '())
  210.       
  211.       ;;收集所有矩形及其边界
  212.       (setq i 0)
  213.       (while (< i (sslength ss))
  214.         (setq ent (ssname ss i))
  215.         (setq obj (vlax-ename->vla-object ent))
  216.         (vla-getboundingbox obj 'minpt 'maxpt)
  217.         (setq minpt (vlax-safearray->list minpt)
  218.               maxpt (vlax-safearray->list maxpt))
  219.         
  220.         (setq allrects (cons (list ent minpt maxpt) allrects))
  221.         (setq i (1+ i))
  222.       )
  223.       
  224.       ;;找出内空的矩形(被其他矩形完全包含的矩形)
  225.       (setq todelete '())
  226.       (foreach rect1 allrects
  227.         (foreach rect2 allrects
  228.           (if (and (not (equal (car rect1) (car rect2)))  ; 不是同一个矩形
  229.                    (IsInside (cadr rect1) (caddr rect1)  ; rect1完全在rect2内部
  230.                             (cadr rect2) (caddr rect2)))
  231.             (setq todelete (cons (car rect1) todelete))
  232.           )
  233.         )
  234.       )
  235.       
  236.       ;;删除内空的矩形
  237.       (if todelete
  238.         (progn
  239.           (setq todelete (vl-remove-duplicates todelete))  ; 去除重复项
  240.           (foreach ent todelete
  241.             (entdel ent)
  242.           )
  243.           (princ (strcat "\n删除了 " (itoa (length todelete)) " 个内空矩形"))
  244.         )
  245.         (princ "\n未找到内空矩形")
  246.       )
  247.     )
  248.     (princ "\n未选择到矩形")
  249.   )
  250.   (princ)
  251. )

  252. ;;判断矩形1是否完全在矩形2内部
  253. (defun IsInside (min1 max1 min2 max2)
  254.   (and
  255.     (>= (car min1) (car min2))
  256.     (>= (cadr min1) (cadr min2))
  257.     (<= (car max1) (car max2))
  258.     (<= (cadr max1) (cadr max2))
  259.   )
  260. )

  261. (princ "\n动态框绘制程序加载完成,输入 DD 运行,输入 DeleteInnerRects 删除内空矩形")
  262. (princ)
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-12 06:39 , Processed in 0.139758 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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