明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 56384|回复: 422

[源码] [已经解决]获取对象包围盒、最小包围盒-----(也适于UCS)

    [复制链接]
发表于 2013-9-17 16:04 | 显示全部楼层 |阅读模式
本帖最后由 自贡黄明儒 于 2013-10-8 14:55 编辑

第三版===================================================================

  1. ;;[功能] 图元当前坐标系下包围盒,4角点坐标
  2. ;|
  3. 4 = 左上;3 = 右上
  4. 1 = 左下;2 = 右下
  5. |;
  6. ;;Flag : T时,返回最小包围盒角点;nil时,返回包围盒角点
  7. ;;说明 1 使用前加载须加载highflybird的程序Matrix-Lib.LSP
  8. ;;     2 作者保留本程序的一切权利,但你可以自由拷贝与复制、修改本程序用于非商业目的
  9. ;;     3 自贡黄明儒 2013年10月8日
  10. ;;示例(HH:Ent4pt (car (entsel)) T),返回UCS坐标系下坐标
  11. (defun HH:Ent4pt (ent Flag / ENT LST MAT MAT1 MAXPT MINPT OBJ UCSFLAG X)
  12.   (cond ((= (type ent) 'ENAME)
  13.   (setq obj (vlax-ename->vla-object ent))
  14. )
  15. ((= (type ent) 'VLA-OBJECT) (setq obj ent))
  16. (T (exit))
  17.   )
  18.   (and Flag
  19.        (setq Mat (Mat:EntityMatrix ent))
  20.        (setq Mat1 (cadr Mat));Mat1 4x4
  21.        (setq Mat (car Mat));Mat 4x4
  22.   )
  23.   (if (= (getvar "WORLDUCS") 0)
  24.     (setq UcsFlag T)
  25.   )
  26.   (cond ((and Flag UcsFlag)
  27.   (vla-TransformBy obj (vlax-tmatrix Mat))
  28. )
  29. (UcsFlag (vla-TransformBy obj (vlax-tmatrix (MAT:u2w))))
  30. (Flag (vla-TransformBy obj (vlax-tmatrix Mat)))
  31.   )
  32.   (vla-GetBoundingBox obj 'minPt 'maxPt)   ;得到包围框
  33.   (setq minPt (vlax-safearray->list minPt))
  34.   (setq maxPt (vlax-safearray->list maxPt))
  35.   (cond ((and Flag UcsFlag)
  36.   (vla-TransformBy obj (vlax-tmatrix Mat1))
  37. )
  38. (UcsFlag (vla-TransformBy obj (vlax-tmatrix (MAT:w2u))))
  39. (Flag (vla-TransformBy obj (vlax-tmatrix Mat1)))
  40.   )
  41.   (setq lst (list minPt
  42.     (list (car maxPt) (cadr minpt) (caddr minPt))
  43.     maxPt
  44.     (list (car minpt) (cadr maxPt) (caddr minPt))
  45.      )
  46.   )
  47.   (COND (Flag nil)
  48. (UcsFlag (setq mat1 (MAT:w2u)))
  49.   )
  50.   (cond ((or Flag UcsFlag)
  51.   (setq lst (mapcar '(lambda (x) (mat:mxp mat1 x)) lst)) ;wcs坐标
  52.   (setq lst (mapcar '(lambda (x) (trans x ent 1)) lst))
  53. )
  54.   )
  55.   lst
  56. )

第二版
===================================================================
;;[功能] 图元当前坐标系下包围盒,4角点坐标
;|
4 = 左上;3 = 右上
1 = 左下;2 = 右下
|;
;;Flag : T时,返回最小包围盒角点;nil时,返回包围盒角点
;;说明 1 使用前加载须加载highflybird的程序Matrix-Lib.LSP
;;     2 作者保留本程序的一切权利,但你可以自由拷贝与复制、修改本程序用于非商业目的。
;;     3 自贡黄明儒 2013年9月27日

  1. ;;[功能] 图元当前坐标系下包围盒,4角点坐标
  2. ;|
  3. 4 = 左上;3 = 右上
  4. 1 = 左下;2 = 右下
  5. |;
  6. ;;Flag : T时,返回最小包围盒角点;nil时,返回包围盒角点
  7. ;;说明 1 使用前加载须加载highflybird的程序Matrix-Lib.LSP
  8. ;;     2 作者保留本程序的一切权利,但你可以自由拷贝与复制、修改本程序用于非商业目的。
  9. ;;     3 自贡黄明儒 2013年9月27日
  10. (defun HH:Ent4pt (ent   Flag   /   ENT   LST   MAT   MAT1   MATLST  MATRIX
  11.     MAXPT   MINPT   OBJ   ORIGIN  REVMAT  UCSFLAG WCSORG  X   XDIR
  12.     YDIR   ZDIR
  13.    )
  14.   ;;1 矩阵的变换与逆变换
  15.   (defun GetMatrix (lst org Revflag / I J MAT)
  16.     (setq mat (vlax-make-safearray vlax-vbDouble '(0 . 3) '(0 . 3)))
  17.     (setq i 0)
  18.     (repeat 3
  19.       (vlax-safearray-put-element mat i 3 (nth i org))     ;平移变换
  20.       (setq j 0)
  21.       (repeat 3
  22. (if RevFlag
  23.    (vlax-safearray-put-element mat i j (nth j (nth i lst))) ;角度逆变换
  24.    (vlax-safearray-put-element mat i j (nth i (nth j lst))) ;角度的变换
  25. )
  26. (setq j (1+ j))
  27.       )
  28.       (setq i (1+ i))
  29.     )
  30.     (vlax-safearray-put-element mat 3 3 1)
  31.     mat           ;返回矩阵
  32.   )
  33.   ;;2 本程序主程序
  34.   (cond ((= (type ent) 'ENAME)
  35.   (setq obj (vlax-ename->vla-object ent))
  36. )
  37. ((= (type ent) 'VLA-OBJECT) (setq obj ent))
  38. (T (exit))
  39.   )
  40.   (and Flag
  41.        (setq Mat (Mat:EntityMatrix ent))
  42.        (setq Mat1 (cadr Mat))
  43.        (setq Mat (car Mat))
  44.   )
  45.   (setq UcsFlag (getvar "WORLDUCS"))
  46.   (if (= UcsFlag 0)         ;UCS与WCS不同
  47.     (setq UcsFlag T         ;设置标志位为true
  48.    xdir   (getvar "UCSXDIR")       ;X方向矢量
  49.    ydir   (getvar "UCSYDIR")       ;Y方向矢量
  50.    zdir   (MAT:vxv xdir ydir)       ;X和Y的方向矢量的叉积
  51.    origin  (getvar "UCSORG")       ;原点
  52.    WcsOrg  (trans '(0 0 0) 0 1)       ;WCS的原点相对UCS的坐标
  53.    matLst  (list xdir ydir zdir)       ;旋转的变换矩阵表
  54.    matrix  (GetMatrix matLst origin nil)      ;从WCS到UCS(ocs)的变换矩阵
  55.    revMat  (GetMatrix matLst WcsOrg T)      ;从UCS(ocs)到WCS的变换矩阵
  56.     )
  57.     (setq UcsFlag nil)         ;否则不予变换
  58.   )
  59.   ;;在UCS下先变换物体到WCS下,取得物体的包围框,然后把物体变换回到UCS
  60.   (cond ((and Flag UcsFlag) (vla-TransformBy obj (vlax-tmatrix Mat)))
  61. (UcsFlag (vla-TransformBy obj revMat))
  62. (Flag (vla-TransformBy obj (vlax-tmatrix Mat)))
  63.   )
  64.   (vla-GetBoundingBox obj 'minPt 'maxPt)      ;得到包围框
  65.   (setq minPt (vlax-safearray->list minPt))
  66.   (setq maxPt (vlax-safearray->list maxPt))
  67.   (cond ((and Flag UcsFlag) (vla-TransformBy obj (vlax-tmatrix Mat1)))
  68. (UcsFlag (vla-TransformBy obj matrix))
  69. (Flag (vla-TransformBy obj (vlax-tmatrix Mat1)))
  70.   )
  71.   (setq lst (list minPt
  72.     (list (car maxPt) (cadr minpt) (caddr minPt))
  73.     maxPt
  74.     (list (car minpt) (cadr maxPt) (caddr minPt))
  75.      )
  76.   )
  77.   (COND (Flag nil)
  78. (UcsFlag (setq mat1 (vlax-safearray->list matrix)))
  79.   )
  80.   (cond ((or Flag UcsFlag)
  81.   (setq lst (mapcar '(lambda (x) (mat:mxp mat1 x)) lst)) ;wcs坐标
  82.   (setq lst (mapcar '(lambda (x) (trans x ent 1)) lst))
  83. )
  84.   )
  85.   lst
  86. )


第一版===================================================================

;;看了highflybird的矩阵和trans,实在没有悟透,请高手们出手,如何获取UCS下旋转过的对象的四个角点,在此首先表示感谢!!
;;主要是想用于求最小包围盒,以便对任何对象画中心线

;;[功能] 图元当前坐标系下包围盒,4角点坐标
;|
4 = 左上;3 = 右上
1 = 左下;2 = 右下
|;
;;Flag : T时,返回最小包围盒角点;nil时,返回包围盒角点
;;说明 1 使用前加载须加载highflybird的程序Matrix-Lib.LSP
;;     2 本程序是在G版的帮助和烧糊了一锅稀饭的代价下,试验出来的
;;     3 本程序是在highflybird选择集最小包围盒基础上发展而来
;;     4 不足之处是用了command,有待改善
;;     5 自贡黄明儒 2013年9月19日 中秋节
;;     6 使用者须保留以上信息
;;示例(HH:Ent4pt (car (entsel)) T),返回UCS坐标系下坐标
(defun HH:Ent4pt (ent   Flag   /   ENT   LST   MATLST  MATRIX  MAXPT   MINPT
    OBJ   ORIGIN  REVMAT  UCSFLAG WCSORG  X   XDIR   YDIR   ZDIR
   )
  ;;1 矩阵的变换与逆变换
  (defun GetMatrix (lst org Revflag / I J MAT)
    (setq mat (vlax-make-safearray vlax-vbDouble '(0 . 3) '(0 . 3)))
    (setq i 0)
    (repeat 3
      (vlax-safearray-put-element mat i 3 (nth i org))     ;平移变换
      (setq j 0)
      (repeat 3
(if RevFlag
   (vlax-safearray-put-element mat i j (nth j (nth i lst))) ;角度逆变换
   (vlax-safearray-put-element mat i j (nth i (nth j lst))) ;角度的变换
)
(setq j (1+ j))
      )
      (setq i (1+ i))
    )
    (vlax-safearray-put-element mat 3 3 1)
    mat           ;返回矩阵
  )
  ;;2 本程序主程序
  (cond ((= (type ent) 'ENAME)
  (setq obj (vlax-ename->vla-object ent))
)
((= (type ent) 'VLA-OBJECT) (setq obj ent))
(T (exit))
  )
  (and Flag (command "_.UCS" "NEW" "Object" ent))
  ;;先判断UCS是否与WCS相同。如是则取得UCS的X方向,
  ;;Y方向,Z方向,UCS原点及WCS的原点相对UCS的坐标点
  ;;然后得到UCS变换矩阵和到WCS的逆变换矩阵
  (setq UcsFlag (getvar "WORLDUCS"))
  (if (= UcsFlag 0)         ;UCS与WCS不同
    (setq UcsFlag T         ;设置标志位为true
   xdir   (getvar "UCSXDIR")       ;X方向矢量
   ydir   (getvar "UCSYDIR")       ;Y方向矢量
   zdir   (MAT:vxv xdir ydir)       ;X和Y的方向矢量的叉积
   origin  (getvar "UCSORG")       ;原点
   WcsOrg  (trans '(0 0 0) 0 1)       ;WCS的原点相对UCS的坐标
   matLst  (list xdir ydir zdir)       ;旋转的变换矩阵表
   matrix  (GetMatrix matLst origin nil)      ;从WCS到UCS(ocs)的变换矩阵
   revMat  (GetMatrix matLst WcsOrg T)      ;从UCS(ocs)到WCS的变换矩阵
    )
    (setq UcsFlag nil)         ;否则不予变换
  )
  ;;在UCS下先变换物体到WCS下,取得物体的包围框,然后把物体变换回到UCS,并把矩形也变换回去
  (and UcsFlag (vla-TransformBy obj revMat))      ;反变换到WCS
  (vla-GetBoundingBox obj 'minPt 'maxPt)      ;得到包围框
  (setq minPt (vlax-safearray->list minPt))
  ;;(setq minPt (trans minPt ent 1))
  (setq maxPt (vlax-safearray->list maxPt))
  (and UcsFlag (vla-TransformBy obj matrix))      ;变换回到UCS
  (and Flag (command "_.UCS" "p"))
  (and UcsFlag (setq matrix (vlax-safearray->list matrix)))
  (setq lst (list minPt
    (list (car maxPt) (cadr minpt) (caddr minPt))
    maxPt
    (list (car minpt) (cadr maxPt) (caddr minPt))
     )
  )           ;ocs坐标?
  (and UcsFlag
       (setq lst (mapcar '(lambda (x) (mat:mxp matrix x)) lst)) ;wcs坐标
       (setq lst (mapcar '(lambda (x) (trans x ent 1)) lst)) ;ucs坐标
  )
  lst
)
;;下面的代码可以验证
;;148.1 [功能] 根据点表画多段线
(defun draw-pline1 (pts)
  (command "_PLINE")
  (mapcar 'command pts)
  (command "c")
)
;;(draw-pline(HH:Ent4pt (car (entsel)) T))
;;(draw-pline(HH:Ent4pt (car (entsel)) nil))

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
"觉得好,就打赏"
还没有人打赏,支持一下

本帖被以下淘专辑推荐:

发表于 2013-9-20 21:44 | 显示全部楼层
;;----------------=={ Minimum Bounding Box }==----------------;;
;;                                                            ;;
;;  Returns the coordinates of the minimum bounding rectangle ;;
;;  surrounding objects in a supplied selection set           ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright ? 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  ss - selection set to process                             ;;
;;  pr - precision of calculation, 0 < pr < 1                 ;;
;;------------------------------------------------------------;;
;;  Returns: coordinates of minimum rectangle framing objects ;;
;;------------------------------------------------------------;;

(defun LM:MinBoundingBox ( ss pr / an ba bb bm cn cv i l mb )
  (if ss
    (progn
      (setq bb
        (LM:ListBoundingBox
          (repeat (setq i (sslength ss))
            (setq l (cons (vla-copy (vlax-ename->vla-object (ssname ss (setq i (1- i))))) l))
          )
        )
      )
      (setq pr (* pr pi)
            cn (apply 'mapcar (cons (function (lambda ( a b ) (/ (+ a b) 2.0))) bb))
            cv (vlax-3D-point cn)
            bm (* (- (caadr bb) (caar bb)) (- (cadadr bb) (cadar bb)))
            mb (cons 0.0 bb)
            an 0
      )
      (while (< (setq an (+ an pr)) pi)
        (foreach x l (vla-rotate x cv pr))
        (setq bb (LM:ListBoundingBox l)
              ba (* (- (caadr bb) (caar bb)) (- (cadadr bb) (cadar bb)))
        )
        (if (< ba bm) (setq bm ba mb (cons an bb)))
      )
      (foreach x l (vla-delete x))
      (LM:RotatePointsByMatrix
        (mapcar
          (function
            (lambda ( a )
              (mapcar (function (lambda ( b ) ((eval b) (cdr mb)))) a)
            )
          )
         '((caar cadar) (caadr cadar) (caadr cadadr) (caar cadadr))
        )
        cn (- (car mb))
      )
    )
  )
)

;;------------------=={ List BoundingBox }==------------------;;
;;                                                            ;;
;;  Returns the coordinates of a rectangle framing all        ;;
;;  objects in a supplied list                                ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright ? 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  lst - list of VLA-Objects to process                      ;;
;;------------------------------------------------------------;;
;;  Returns:  coordinates of rectangle framing objects        ;;
;;------------------------------------------------------------;;

(defun LM:ListBoundingBox ( lst / l1 l2 ll ur )
  (foreach obj lst
    (vla-getboundingbox obj 'll 'ur)
    (setq l1 (cons (vlax-safearray->list ll) l1)
          l2 (cons (vlax-safearray->list ur) l2)
    )
  )
  (mapcar
    (function (lambda ( a b ) (apply 'mapcar (cons a b))))
   '(min max) (list l1 l2)
  )
)

;;--------------=={ Rotate Points by Matrix }==---------------;;
;;                                                            ;;
;;  Performs a Rotation transformation on a list of points    ;;
;;------------------------------------------------------------;;
;;  Author: Lee Mac, Copyright ? 2011 - www.lee-mac.com       ;;
;;------------------------------------------------------------;;
;;  Arguments:                                                ;;
;;  l - list of points to be rotated                          ;;
;;  p - base point for rotation (in CS of Point List)         ;;
;;  a - angle of rotation                                     ;;
;;------------------------------------------------------------;;

(defun LM:RotatePointsByMatrix ( l p a / m )
  (setq m
    (list
      (list (cos a) (sin (- a)) 0.0)
      (list (sin a) (cos a)     0.0)
      (list   0.0     0.0       1.0)
    )
  )
  (setq p (mapcar '- p (mxv m p)))
  (mapcar (function (lambda ( x ) (mapcar '+ (mxv m x) p))) l)
)

;; Matrix x Vector - Vladimir Nesterovsky
;; Args: m - nxn matrix, v - vector in R^n

(defun mxv ( m v )
  (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
)



(defun c:test ( / s )
  (if (setq s (ssget "_:L"))
    (entmakex
      (append
        (list
          (cons 0 "LWPOLYLINE")
          (cons 100 "AcDbEntity")
          (cons 100 "AcDbPolyline")
          (cons 90 4)
          (cons 70 1)
        )
        (mapcar '(lambda ( p ) (cons 10 p)) (LM:MinBoundingBox s 0.01))
      )
    )
  )
  (princ)
)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

点评

说下返回4角点的顺序吧?  发表于 2019-11-5 21:08
有不规则多边形的凸包多边形吗?不要高飞兄的,他的太长了,包罗万象,我需最简洁的  发表于 2018-5-26 11:34

评分

参与人数 1明经币 +1 收起 理由
自贡黄明儒 + 1 淡定

查看全部评分

回复 支持 1 反对 0

使用道具 举报

发表于 2019-8-20 18:08 来自手机 | 显示全部楼层
最近在做批量转PDF ,被这个包围盒折腾蒙了,请教一下,这个同用trans pt 0 2 区别是什么,我用这个方法,程序调试也通过了,谢谢指点
发表于 2013-9-17 16:24 | 显示全部楼层
  1. ;;返回Text、 MText的左下角点 右下角点 右上角点 左上角点
  2. (defun getTextBox (EN / ENX L B R N W H J O)
  3.   (cond
  4.     ((= 'VLA-OBJECT (type en))
  5.      (setq enx (entget (vlax-vla-object->ename en)))
  6.      )
  7.     ((= 'ename (type en)) (setq enx (entget en)))
  8.     ((= 'list (type en)) (setq enx en))
  9.   )
  10.   (setq        l
  11.          (cond
  12.            ((= "TEXT" (cdr (assoc 0 enx)))
  13.             (setq b (cdr (assoc 10 enx))
  14.                   r (cdr (assoc 50 enx))
  15.                   l (textbox enx)
  16.                   n (cdr (assoc 210 enx))
  17.             )
  18.             (list
  19.               (list (caar l) (cadar l))
  20.               (list (caadr l) (cadar l))
  21.               (list (caadr l) (cadadr l))
  22.               (list (caar l) (cadadr l))
  23.             )
  24.            )
  25.            ((= "MTEXT" (cdr (assoc 0 enx)))
  26.             (setq n (cdr (assoc 210 enx))
  27.                   b (trans (cdr (assoc 10 enx)) 0 n)
  28.                   r (angle '(0.0 0.0 0.0) (trans (cdr (assoc 11 enx)) 0 n))
  29.                   w (cdr (assoc 42 enx))
  30.                   h (cdr (assoc 43 enx))
  31.                   j (cdr (assoc 71 enx))
  32.                   o (list
  33.                       (cond
  34.                         ((member j '(2 5 8)) (/ w -2.0))
  35.                         ((member j '(3 6 9)) (- w))
  36.                         (0.0)
  37.                       )
  38.                       (cond
  39.                         ((member j '(1 2 3)) (- h))
  40.                         ((member j '(4 5 6)) (/ h -2.0))
  41.                         (0.0)
  42.                       )
  43.                     )
  44.             )
  45.             (list
  46.               (list (car o) (cadr o))
  47.               (list (+ (car o) w) (cadr o))
  48.               (list (+ (car o) w) (+ (cadr o) h))
  49.               (list (car o) (+ (cadr o) h))
  50.             )
  51.            )
  52.          )
  53.   )
  54.   (setq        l
  55.          ((lambda (m)
  56.             (mapcar
  57.               '(lambda (p)
  58.                  (mapcar '+
  59.                          (mapcar '(lambda (r) (apply '+ (mapcar '* r p))) m)
  60.                          b
  61.                  )
  62.                )
  63.               l
  64.             )
  65.           )
  66.            (list
  67.              (list (cos r) (sin (- r)) 0.0)
  68.              (list (sin r) (cos r) 0.0)
  69.              '(0.0 0.0 1.0)
  70.            )
  71.          )
  72.   )
  73.   (mapcar '(lambda (x) (trans x n 0)) l)
  74. )

点评

牛! 函数我收下了,谢谢!!  发表于 2020-11-9 16:06

评分

参与人数 1明经币 +1 收起 理由
自贡黄明儒 + 1 很给力!

查看全部评分

 楼主| 发表于 2013-9-17 16:27 | 显示全部楼层
Gu_xl 发表于 2013-9-17 16:24

非常感谢信G版,这么快就搞定了。请问对矩形,块有效吗?
发表于 2013-9-17 16:28 | 显示全部楼层
自贡黄明儒 发表于 2013-9-17 16:27
非常感谢信G版,这么快就搞定了。请问对矩形,块有效吗?

只针对文字!
发表于 2013-9-17 16:34 | 显示全部楼层
自贡黄明儒 发表于 2013-9-17 16:27
非常感谢信G版,这么快就搞定了。请问对矩形,块有效吗?

其他实体的可搜索高飞鸟的凸包、最小包围盒等帖子,
 楼主| 发表于 2013-9-17 16:41 | 显示全部楼层
Gu_xl 发表于 2013-9-17 16:34
其他实体的可搜索高飞鸟的凸包、最小包围盒等帖子,

高飞鸟的最小包围盒,他是画了一个矩形,最后用一句(vla-TransformBy (vlax-ename->vla-object (entlast)) matrix),如果再获取矩形的四角角点,但好象不太好

  1. ;;下面这段代码是用Highflybird的包围盒改的。
  2. (defun c:w1 (/ ENT I MATLST MATRIX OBJ ORIGIN REVMAT SEL UCSFLAG WCSORG        XDIR YDIR
  3.              ZDIR)
  4.   ;;矩阵的变换与逆变换
  5.   (defun GetMatrix (lst org Revflag / mat i j)
  6.     (setq mat (vlax-make-safearray vlax-vbDouble '(0 . 3) '(0 . 3)))
  7.                                                   ;初始化一个4X4的矩阵
  8.     (setq i 0)
  9.     (repeat 3
  10.       (vlax-safearray-put-element mat i 3 (nth i org)) ;平移变换
  11.       (setq j 0)
  12.       (repeat 3
  13.         (if RevFlag
  14.           (vlax-safearray-put-element mat i j (nth j (nth i lst))) ;角度逆变换
  15.           (vlax-safearray-put-element mat i j (nth i (nth j lst))) ;角度的变换
  16.         )
  17.         (setq j (1+ j))
  18.       )
  19.       (setq i (1+ i))
  20.     )
  21.     (vlax-safearray-put-element mat 3 3 1)
  22.     mat                                                  ;返回矩阵
  23.   )
  24.   ;;构造矩形
  25.   (defun Make-Rectange (pt1 pt2)
  26.     (entmake
  27.       (list
  28.         '(0 . "LWPOLYLINE")                          ;轻多段线
  29.         '(100 . "AcDbEntity")
  30.         '(100 . "AcDbPolyline")
  31.         '(90 . 4)                                  ;四个顶点
  32.         '(70 . 1)                                  ;闭合
  33.         (cons 38 (caddr pt1))                          ;高程
  34.         (cons 10 (list (car pt1) (cadr pt1)))          ;左下角
  35.         (cons 10 (list (car pt2) (cadr pt1)))          ;右下角
  36.         (cons 10 (list (car pt2) (cadr pt2)))          ;右上角
  37.         (cons 10 (list (car pt1) (cadr pt2)))          ;左上角
  38.         (cons 210 '(0 0 1))                          ;法线方向
  39.       )
  40.     )
  41.   )

  42.   ;;在UCS下先变换物体到WCS下,取得每个物体的包围框,
  43.   ;;求出包围框集合的最小XY,最大XY,并用矩形框画出来
  44.   ;;然后把物体变换回到UCS,并把矩形也变换回去
  45.   (if (setq ent (car (entsel)))
  46.     ;;选择物体
  47.     (progn
  48.       (setq minPt (vlax-make-safearray vlax-vbdouble '(0 . 2))) ;左下角点
  49.       (setq maxPt (vlax-make-safearray vlax-vbdouble '(0 . 2))) ;右上角点

  50.       (command "_.UCS" "NEW" "Object" ent)

  51.       ;;先判断UCS是否与WCS相同。如是则取得UCS的X方向,
  52.       ;;Y方向,Z方向,UCS原点及WCS的原点相对UCS的坐标点
  53.       ;;然后得到UCS变换矩阵和到WCS的逆变换矩阵
  54.       (setq UcsFlag (getvar "WORLDUCS"))
  55.       (if (= UcsFlag 0)                                  ;UCS是否与WCS相同
  56.         (setq UcsFlag T                                  ;设置标志位为true
  57.               xdir    (getvar "UCSXDIR")          ;X方向矢量
  58.               ydir    (getvar "UCSYDIR")          ;Y方向矢量
  59.               zdir    (MAT:vxv xdir ydir)          ;X和Y的方向矢量的叉积
  60.               origin  (getvar "UCSORG")                  ;原点
  61.               WcsOrg  (trans '(0 0 0) 0 1)          ;WCS的原点相对UCS的坐标
  62.               matLst  (list xdir ydir zdir)          ;旋转的变换矩阵表
  63.               matrix  (GetMatrix matLst origin nil) ;从WCS到UCS的变换矩阵
  64.               revMat  (GetMatrix matLst WcsOrg T) ;从UCS到WCS的变换矩阵
  65.         )
  66.         (setq UcsFlag nil)                          ;否则不予变换
  67.       )
  68.       (setq obj (vlax-ename->vla-object ent))          ;obj对象
  69.       (and UcsFlag (vla-TransformBy obj revMat))  ;反变换到WCS
  70.       (vla-GetBoundingBox obj 'minpt 'maxpt)          ;得到包围框

  71.       (setq minPt (vlax-safearray->list minPt))
  72.       (setq maxPt (vlax-safearray->list maxPt))
  73.       (and UcsFlag (vla-TransformBy obj matrix))  ;变换回到UCS

  74.       (command "_.UCS" "P")

  75.       (and
  76.         (make-Rectange minPt maxPt)                  ;构造边框
  77.         UcsFlag                                          ;如果UCS的话
  78.         (vla-TransformBy (vlax-ename->vla-object (entlast)) matrix)
  79.       )
  80.     )
  81.   )
  82.   (princ)
  83. )
 楼主| 发表于 2013-9-17 16:46 | 显示全部楼层
本帖最后由 自贡黄明儒 于 2013-9-17 16:47 编辑

我是想直接取得对象的四个角点,而且是通用的。
确又搞不定
发表于 2013-9-17 16:50 | 显示全部楼层
自贡黄明儒 发表于 2013-9-17 16:46
我是想直接取得对象的四个角点,而且是通用的。
确又搞不定

呵呵,高飞鸟的矩阵运算必须要学会呦!
发表于 2013-9-17 19:40 | 显示全部楼层
本帖最后由 namezg 于 2013-9-18 21:04 编辑

最近刚写的
  1. ;包围盒转四角点列表wcs
  2. ;box--包围盒wcs
  3. (defun zg-BoundingBox->List (box / pt1 pt2 pt3 pt4)
  4.         (setq pt1 (car box))
  5.         (setq pt3 (cadr box))
  6.         (setq pt2 (list (car pt3) (cadr pt1) (caddr pt1)))
  7.         (setq pt4 (list (car pt1) (cadr pt3) (caddr pt1)))
  8.         (list pt1 pt2 pt3 pt4)
  9. )
  10. ;功能:从一个坐标系统到另一个坐标系统的变换矩阵
  11. ;参数:from -- 源坐标系统 整数代码    0 世界坐标系(WCS) 1 用户坐标系(当前 UCS)
  12. ;      to   -- 目标坐标系统 整数代码  0 世界坐标系(WCS) 1 用户坐标系(当前 UCS)
  13. ;返回值:(list 源坐标系统->目标坐标系统的变换矩阵 目标坐标系统->源坐标系统的变换矩阵)
  14. (defun zg-matrix-trans (from to / RMat Disp InvRMat InvDisp)
  15.         (setq RMat
  16.                 (mapcar
  17.                         '(lambda (v) (trans v from to t))
  18.                         '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  19.                 )
  20.         )
  21.         (setq Disp (trans '(0. 0. 0.) to from))
  22.         (setq InvRMat (apply 'mapcar (cons 'list RMat)))
  23.         (setq InvDisp (trans '(0. 0. 0.) from to))
  24.         (mapcar
  25.                 '(lambda (x)
  26.                         (append
  27.                                 (mapcar 'append (car x) (mapcar 'list (cadr x)))
  28.                                 '((0. 0. 0. 1.))
  29.                         )
  30.                 )
  31.                 (list (list RMat Disp) (list InvRMat InvDisp))
  32.         )
  33. )
  34. ;已知一点和点的三维转换矩阵,获得新的点坐标
  35. ;pt -- 三维点坐标
  36. ;mat -- 三维转换矩阵(caddr (nentsel))或(caddr (nentselp))
  37. (defun mxp (mat pt / vector num matp new_pt)
  38. (if (= (length pt) 2)
  39.   (setq pt (append pt '(0.0)))
  40. )
  41. (setq vector (append pt '(1.0)))
  42. (if mat
  43.   (progn
  44.    (setq num (length (car mat)))
  45.    (cond
  46.     ;(caddr (nentsel))
  47.     ((= num 3)
  48.      (setq matp (apply 'mapcar (cons 'list mat)))
  49.     )
  50.     ;(caddr (nentselp))
  51.     ((= num 4)
  52.      (setq matp (reverse (cdr (reverse mat))))
  53.     )
  54.    )
  55.    (setq new_pt (mapcar '(lambda (x) (apply '+ (mapcar '* x vector))) matp))
  56.   )
  57. )
  58. )
  59. ;功能:获得单一对象在UCS坐标系中的包围盒四个角点的WCS坐标
  60. ;ename--图元名
  61. (defun zg-GetObjectUCSBoundingBox (ename / ll rr box wcsptlst MatpLlist UCS2WCSMatp obj WCS2UCSMatp ptlst)
  62.         (if (car (atoms-family 1 '("vl-load-com")))
  63.                 (vl-load-com)
  64.         )
  65.         (if (= (getvar "worlducs") 1)
  66.                 ;WCS与UCS相同
  67.                 (if (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-GetBoundingBox (list (vlax-ename->vla-object ename) 'll 'rr))))
  68.                         (progn
  69.                                 (setq box (list (vlax-safearray->list ll) (vlax-safearray->list rr)))
  70.                                 (setq wcsptlst (zg-BoundingBox->List box))
  71.                         )
  72.                 )
  73.                 ;WCS与UCS不同
  74.                 (progn
  75.                         (setq MatpLlist (zg-matrix-trans 1 0))
  76.                         (setq UCS2WCSMatp (car MatpLlist))
  77.                         (setq WCS2UCSMatp (cadr MatpLlist))
  78.                         (setq obj (vlax-ename->vla-object ename))
  79.                         (vla-TransformBy obj (vlax-tmatrix UCS2WCSMatp));UCS->WCS
  80.                         (if (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-GetBoundingBox (list obj 'll 'rr))))
  81.                                 (setq box (list (vlax-safearray->list ll) (vlax-safearray->list rr)))
  82.                         )
  83.                         (vla-TransformBy obj (vlax-tmatrix WCS2UCSMatp));WCS->UCS
  84.                         (if box
  85.                                 (progn
  86.                                         (setq ptlst (zg-BoundingBox->List box))
  87.                                         (setq wcsptlst (mapcar '(lambda (pt) (mxp WCS2UCSMatp pt)) ptlst))
  88.                                 )
  89.                         )
  90.                 )
  91.         )
  92.         wcsptlst
  93. )

评分

参与人数 1明经币 +1 收起 理由
自贡黄明儒 + 1 很给力!

查看全部评分

发表于 2013-9-18 07:34 来自手机 | 显示全部楼层
本帖最后由 namezg 于 2013-9-18 08:01 编辑

mxp函数忘发了.现在在外面.回头补上.

已补全了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-17 14:30 , Processed in 0.279442 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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