明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 12812|回复: 24

[【高飞鸟】] 【飞鸟集】UCS的变换矩阵及其逆变换矩阵

    [复制链接]
发表于 2011-6-24 12:53 | 显示全部楼层 |阅读模式
这里提供一个函数,得到当前UCS下的变化矩阵和逆变换矩阵。

  1. ;;;UCS到WCS的变换矩阵及其WCS到UCS的变换矩阵                             
  2. ;;;the transformation matrix of UCS to WCS and WCS to UCS.              
  3. (defun UCS2WCS (/ xdir ydir zdir UcsOrg WcsOrg matlst revlst matrix)
  4.   (defun AppendMatrix (lst org)
  5.     (append
  6.       (mapcar 'append lst (mapcar 'list org))
  7.       '((0. 0. 0. 1.))
  8.     )
  9.   )
  10.   (if (zerop (getvar "WORLDUCS"))                    ;如果不同于WCS
  11.     (setq xdir   (getvar "UCSXDIR")                     ;X方向
  12.              ydir   (getvar "UCSYDIR")                     ;Y方向
  13.              zdir   (G:CrossProductor xdir ydir)         ;Z方向等于X方向叉乘Y方向
  14.              UcsOrg (getvar "UCSORG")                  ;UCS原点
  15.              WcsOrg (trans '(0 0 0) 0 1)                   ;WCS原点相对于UCS的坐标
  16.              matLst (list xdir ydir zdir)                        ;UCS的旋转矩阵
  17.              RevLst (trp matLst)                               ;UCS的旋转矩阵的逆
  18.              matrix (list
  19.                       (AppendMatrix matlst WcsOrg)        ;UCS到WCS的变换矩阵
  20.                       (AppendMatrix RevLst UcsOrg)        ;WCS到UCS的变换矩阵
  21.                     )
  22.     )
  23.     (list
  24.       '((1. 0. 0. 0.) (0. 1. 0. 0.) (0. 0. 1. 0.) (0. 0. 0. 1.))  ;世界坐标系下是单位矩阵
  25.       '((1. 0. 0. 0.) (0. 1. 0. 0.) (0. 0. 1. 0.) (0. 0. 0. 1.))  ;世界坐标系下是单位矩阵
  26.     )
  27.   )
  28. )

  29. ;;; 矢量的点积                                                         
  30. ;;; VXV Returns the dot product of 2 vectors                           
  31. (defun vxv (v1 v2)
  32.   (apply '+ (mapcar '* v1 v2))
  33. )
  34. ;;; 矢量转置                                                            
  35. ;;; TRP Transpose a matrix -Doug Wilson-                                
  36. (defun trp (m)
  37.   (apply 'mapcar (cons 'list m))
  38. )
  39. ;;; 矢量的矩阵变换                                                      
  40. ;;; MXV Apply a transformation matrix to a vector -Vladimir Nesterovsky-
  41. (defun mxv (m v)
  42.   (mapcar (function (lambda (r) (vxv r v))) m)
  43. )
  44. ;;; 矩阵相乘                                                            
  45. ;;; MXM Multiply two matrices -Vladimir Nesterovsky-                    
  46. (defun mxm (m q)
  47.   (mapcar (function (lambda (r) (mxv (trp q) r))) m)
  48. )
  49. ;;;两矢量的叉积                                                         
  50. ;;; CrossProductor --vec1 * vec2                                       
  51. (defun G:CrossProductor (vec1 vec2 / a b c d e f)                 
  52.   (setq a (car   vec1))
  53.   (setq b (cadr  vec1))
  54.   (setq c (caddr vec1))
  55.   (setq d (car   vec2))
  56.   (setq e (cadr  vec2))
  57.   (setq f (caddr vec2))
  58.   (list
  59.     (- (* b f) (* c e))
  60.     (- (* c d) (* a f))
  61.     (- (* a e) (* b d))
  62.   )
  63. )
以下作为测试
  1.                                                   
  2. (defun c:test(/ ent obj mat)
  3.   (if (setq ent (car (entsel)))
  4.     (progn
  5.       (setq obj (vlax-ename->vla-object ent))
  6.       (setq mat (ucs2wcs))
  7.       (vla-TransformBy obj (vlax-tmatrix (car  mat)))                   ;UCS->WCS
  8.       (command ".select" ent pause)
  9.       (vla-TransformBy obj (vlax-tmatrix (cadr mat)))                  ;WCS->UCS
  10.     )
  11.   )
  12. )
该贴已经同步到 highflybird的微博

"觉得好,就打赏"
    共1人打赏

本帖被以下淘专辑推荐:

发表于 2022-12-5 14:24 | 显示全部楼层
此帖乃神仙打架 凡人不懂
 楼主| 发表于 2011-6-24 19:19 | 显示全部楼层
Lee Mac 的,更简洁


  1. (defun LM:UCS2WCS nil
  2.   (append
  3.     (mapcar 'append
  4.       (mapcar
  5.         (function
  6.           (lambda ( v ) (trans v 1 0 t))
  7.         )
  8.        '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  9.       )
  10.       (mapcar 'list (trans '(0. 0. 0.) 0 1))
  11.     )
  12.    '((0. 0. 0. 1.))
  13.   )
  14. )

  15. (defun LM:WCS2UCS nil
  16.   (append
  17.     (mapcar 'append
  18.       (mapcar
  19.         (function
  20.           (lambda ( v ) (trans v 0 1 t))
  21.         )
  22.        '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  23.       )
  24.       (mapcar 'list (trans '(0. 0. 0.) 1 0))
  25.     )
  26.    '((0. 0. 0. 1.))
  27.   )
  28. )

发表于 2011-6-25 11:36 | 显示全部楼层
本帖最后由 狂刀lxx 于 2011-6-25 11:39 编辑

不错,我再帮简化一下
  1. ;|ucs-wcs转换矩阵 by LEE MAC  简化by dreamsky 2011.6|;
  2. (defun tranx (x y)
  3.   (append
  4.     (mapcar 'append
  5.    (mapcar (function(lambda(v)(trans v x y t)))
  6.     '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  7.     )
  8.           (mapcar 'list (trans '(0. 0. 0.) y x))
  9.     )
  10.   '((0. 0. 0. 1.))
  11.   )
  12. )
  13. (defun u2w ()(tranx 1 0)) ;;ucs转wcs矩阵
  14. (defun w2u ()(tranx 0 1));;wcs转ucs矩阵
发表于 2011-6-25 12:07 | 显示全部楼层
高 实在高  
 楼主| 发表于 2011-6-26 08:42 | 显示全部楼层
其实可以更简单的。
  1. (vla-GetUCSMatrix
  2.   (vla-item
  3.     (vla-get-UserCoordinateSystems
  4.       (vla-get-ActiveDocument
  5.         (vlax-get-acad-object))) i))    ;;;i --->第i个ucs

发表于 2011-6-26 08:47 | 显示全部楼层
本帖最后由 highflybir 于 2011-6-26 08:58 编辑

回复 狂刀lxx 的帖子



  1. ;;;Hence the code would only be able to create a transformation matrix to transfrom from WCS to
  2. ;;;a coordinate system with origin, normal and rotation as supplied.
  3. 下面的代码可以创建一个变换矩阵,这个矩阵定义了原点,法线,和旋转角度。
  4. (defun LM:UCSMatrix ( org norm ang )
  5.   (append
  6.     (mapcar 'append
  7.       (mxm
  8.         (mapcar
  9.           (function
  10.             (lambda ( v ) (trans v 0 norm t))
  11.           )
  12.          '((1. 0. 0.) (0. 1. 0.) (0. 0. 1.))
  13.         )
  14.         (list
  15.           (list (cos ang) (- (sin ang)) 0.)
  16.           (list (sin ang)    (cos ang)  0.)
  17.           (list    0.            0.     1.)
  18.         )
  19.       )
  20.       (mapcar 'list (trans org norm 0))
  21.     )
  22.    '((0. 0. 0. 1.))
  23.   )
  24. )

  25. ;; Matrix x Vector  ~  Vladimir Nesterovsky
  26. (defun mxv ( mat vec )
  27.   (mapcar '(lambda ( row ) (apply '+ (mapcar '* row vec))) mat)
  28. )

  29. ;; Matrix x Matrix  ~  Vladimir Nesterovsky
  30. (defun mxm ( m q )
  31.   (mapcar (function (lambda ( r ) (mxv (trp q) r))) m)
  32. )

  33. ;; Matrix Transpose  ~  Doug Wilson
  34. (defun trp ( m )
  35.   (apply 'mapcar (cons 'list m))
  36. )
发表于 2011-6-26 12:44 | 显示全部楼层
高手好多,发帖做记号
 楼主| 发表于 2011-6-26 16:05 | 显示全部楼层
本帖最后由 highflybird 于 2011-6-26 16:07 编辑

顺便说一下:
我开始的矩阵变换还是有用的:

如果一个坐标系统是定义成(UCSorg UCSXDir UCSYDir) -->CAD中UCS定义的方法
那么可按照下面的函数得到转换矩阵和逆转换矩阵。
  1. ;;;UCS变换矩阵
  2. (defun UCSMatrix (Org xAxis yAxis / d1 d2 xNrm yNrm zNrm RotMat InvMat
  3.                       WcsOrg UCS->WCS WCS->UCS matrix)
  4.   (setq d1 (distance '(0 0 0) xAxis))
  5.   (setq d2 (distance '(0 0 0) yAxis))
  6.   (if (or (zerop d1) (zerop d2))
  7.     '((1. 0. 0. 0.) (0. 1. 0. 0.) (0. 0. 1. 0.) (0. 0. 0. 1.))
  8.     (setq xNrm    (mapcar '/ xAxis (list d1 d1 d1))    ;X Axis
  9.    yNrm    (mapcar '/ yAxis (list d2 d2 d2))    ;Y Axis
  10.    zNrm    (G:CrossProductor xNrm yNrm)    ;Z Axis
  11.    RotMat   (list xNrm yNrm zNrm)     ;Rotation matrix
  12.    InvMat   (trp RotMat)      ;Inverse Rotation matrix
  13.    WcsOrg   (mxv RotMat (mapcar '- Org))    ;The coordinate of WCS origin relate to UCS
  14.    UCS->WCS (append (mapcar 'append RotMat (mapcar 'list WcsOrg))  '((0. 0. 0. 1.)))         
  15.    WCS->UCS (append (mapcar 'append InvMat (mapcar 'list Org)) '((0. 0. 0. 1.)))
  16.    matrix   (list UCS->WCS WCS->UCS)    ;return two matrices
  17.     )
  18.   )
  19. )

例如下面的测试:
  1. (defun c:test()
  2.   (if (setq Ent (car (entsel)))
  3.     (progn
  4.       (setq Org (getvar "ucsorg"))
  5.       (setq XDr (getvar "ucsxdir"))
  6.       (setq ydr (getvar "ucsydir"))
  7.       (setq Obj (vlax-ename->vla-object Ent))
  8.       (setq Mat (UCSMatrix Org xdr ydr))
  9.       (vla-TransformBy Obj (vlax-tmatrix (car  Mat)))                   ;UCS->WCS
  10.       (command ".select" ent pause)
  11.       (vla-TransformBy Obj (vlax-tmatrix (cadr Mat)))                   ;WCS->UCS
  12.     )
  13.   )
  14. )

 楼主| 发表于 2011-6-26 16:10 | 显示全部楼层
回复 highflybird 的帖子

另外附上旋转矩阵函数:
这个旋转矩阵的参数是(旋转角度,旋转轴,旋转基点)

  1. ;;;Ang ---旋转角度
  2. ;;;Nrm ---旋转轴(矢量)(WCS下的)
  3. ;;;Org ---旋转基点 (WCS下的)
  4. (defun RotationMatrix (Ang Nrm Org / A B C dist M N PT WX WY WZ)
  5.   (setq dist (distance '(0 0 0) Nrm))
  6.   (if (> dist 1e-8)
  7.     (setq N  (mapcar '/ nrm (list dist dist dist))
  8.    wx (car N)
  9.    wy (cadr N)
  10.    wz (caddr N)
  11.    A  (cos Ang)
  12.    B  (sin Ang)
  13.    C  (- 1 A)
  14.    M  (list (list (+ A (* wx wx C))
  15.     (- (* wx wy C) (* wz B))
  16.     (+ (* wy B) (* wx wz C))
  17.      )
  18.      (list (+ (* wz B) (* wx wy C))
  19.     (+ A (* wy wy C))
  20.     (- (* wy wz C) (* wx B))
  21.      )
  22.      (list (- (* wx wz C) (* wy B))
  23.     (+ (* wx B) (* wy wz C))
  24.     (+ A (* wz wz C))
  25.      )
  26.       )
  27.    pt (mapcar '- org (mxv M org))
  28.    M  (append (mapcar 'append M (mapcar 'list pt))
  29.        '((0. 0. 0. 1.))
  30.       )
  31.     )
  32.     '((1. 0. 0. 0.) (0. 1. 0. 0.) (0. 0. 1. 0.) (0. 0. 0. 1.))
  33.   )
  34. )

例如下面的测试例子:

  1. (defun c:ttt (/ Ent Obj Mat Org Vec Ang Nrm)
  2.   (setq app (vlax-get-acad-object))
  3.   (setq doc (vla-get-ActiveDocument app))
  4.   (setq ucs (vla-get-UserCoordinateSystems doc))
  5.   (setq i 0)
  6.   (repeat (vla-get-Count ucs)
  7.     (setq u (vla-item ucs i))
  8.     (vlax-dump-object u  T)
  9.     (setq i (1+ i))   
  10.   )
  11.   (if (and (setq Ent (car (entsel)))
  12.     (setq Org (getpoint "\nInput origin point of rotation:"))
  13.     (setq Vec (getpoint Org "\nInput the Axis vector of rotation:"))
  14.     (setq Ang (getangle "\nInput the angle of rotation:"))
  15.       )
  16.     (progn
  17.       (setq Org (trans Org 1 0))
  18.       (setq Vec (trans Vec 1 0))
  19.       (setq Nrm (mapcar '- Vec Org))
  20.       (setq Obj (vlax-ename->vla-object Ent))
  21.       (setq Mat (RotationMatrix Ang Nrm Org))
  22.       (vla-TransformBy Obj (vlax-tmatrix Mat))                   ;旋转矩阵
  23.     )
  24.   )
  25. )

发表于 2011-6-26 16:12 | 显示全部楼层
回复 highflybird 的帖子

用户稍加修改,就可以用这个函数替代rotate3d,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-4-18 21:19 , Processed in 0.203176 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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