明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4715|回复: 10

【求助】如何:获得图块的矩阵

  [复制链接]
发表于 2009-2-3 13:02 | 显示全部楼层 |阅读模式
本帖最后由 作者 于 2009-2-4 19:56:18 编辑

下面这段函数获取普通一般块的矩阵没有问题,对于嵌套、旋转、不等比例缩放、镜像的块,取得的矩阵好像不正确,与 nentselp 返回的矩阵不同,请问怎么才能修改为更为通用的函数,附件为一个较复杂的嵌套块,可供测试!
该函数是正确的,没有问题,参数必须保证是图块图元名!唯一不足之处是:对于不等比例缩放的块和镜像后的块,获得的矩阵不准确!此两种情况再加上选装,就更不准了!
  1. ;|功能:获得块的矩阵----支持三维-----------------
  2. (blkmat (vlax-ename->vla-object(car(entsel))))
  3. |;
  4. (defun blkmat (vobj / mxm origin ang inspt zdir xdir ydir rmat movmatrix resmatrix)
  5.   (defun mxm (m q / qt)
  6.     (setq qt (apply 'mapcar (cons 'list q)))
  7.     (mapcar '(lambda (x) (mapcar '(lambda (y) (apply '+ (mapcar '* y x))) qt)) m)
  8.   )
  9.   (and
  10.     (setq origin(vlax-get (vlax-invoke (vlax-get (vlax-get (vlax-get-acad-object) "Activedocument") "blocks")
  11.                 "item"  (vlax-get vobj "name")) "origin"))
  12.     (setq ang (vlax-get vobj "Rotation"))
  13.     (setq inspt (mapcar '- (vlax-get vobj "InsertionPoint") origin));需要增加块定义原点的判断~~~~
  14.     (setq zdir (vlax-get vobj "Normal"))
  15.     (setq xdir(trans (list (cos ang)(sin ang) 0) zdir 0))
  16.     (setq ydir(list (- (* (cadr zdir)(caddr xdir)) (* (caddr zdir)(cadr xdir)));叉乘得到Y轴方向-------
  17.             (- (* (caddr zdir)(car xdir)) (* (car zdir)(caddr xdir)))
  18.             (- (* (car zdir)(cadr xdir)) (* (cadr zdir)(car xdir)))))
  19.     (setq rmat(list (list (car xdir)(car ydir) (car zdir) 0)
  20.             (list (cadr xdir)(cadr ydir)(cadr zdir) 0)
  21.             (list (caddr xdir)(caddr ydir)(caddr zdir) 0)))
  22.     (setq rmat(mapcar '(lambda(x y)(mapcar '(lambda(m)(* m y)) x))
  23.                  rmat
  24.                  (list (vlax-get vobj "XScaleFactor")
  25.                        (vlax-get vobj "YScaleFactor")
  26.                        (vlax-get vobj "ZScaleFactor")
  27.                        )))
  28.     (setq rmat(list (car rmat) (cadr rmat) (caddr rmat) '(0 0 0 1)))
  29.     (setq movmatrix(list (list 1 0 0 (car inspt))(list 0 1 0 (cadr inspt))(list 0 0 1 (caddr inspt))
  30.                      '(0 0 0 1)))
  31.     (setq rmat (mxm movmatrix rmat))
  32.   )
  33.   rmat
  34. )
 楼主| 发表于 2009-2-21 22:18 | 显示全部楼层
我贴一个我修改后的函数,和ObjMatrix得出来的应该是一样的:
  1. (defun InsertMat (InsertEname /    InsertEList ZAxis
  2.     NCSXAxis    InsertAngle tmp1       tmp2
  3.     Orig
  4.    )
  5.   (setq ZAxis     (cdr (assoc 210 (setq InsertEList (entget InsertEName))))
  6. InsertAngle (cdr (assoc 50 InsertEList))
  7. NCSXAxis    (trans (list (cos InsertAngle) (- (sin InsertAngle)) 0.0)
  8.       (cdr (assoc 210 InsertEList))
  9.       0
  10.       )
  11. Orig     (mapcar
  12.         '-
  13.         (vlax-get
  14.    (vla-item
  15.      (vla-get-blocks
  16.        (vla-get-activedocument (vlax-get-acad-object))
  17.      )
  18.      (vlax-get (vlax-ename->vla-object InsertEName) 'Name)
  19.    )
  20.    'Origin
  21.         )
  22.       )
  23.   )
  24.   ;; Set up the return value
  25.   ;; The insertion point of the insert
  26.   (setq tmp1 (trans (cdr (assoc 10 InsertEList)) ZAxis 0))
  27.   ;; The scale factors
  28.   (setq tmp2 (list (cdr (assoc 41 InsertEList))
  29.      (cdr (assoc 42 InsertEList))
  30.      (cdr (assoc 43 InsertEList))
  31.       )
  32.   )
  33.   (mxm
  34.     (list (append (mapcar '* NCSXAxis tmp2) (list (nth 0 tmp1)))
  35.    (append (mapcar '* (VectorCrossProduct ZAxis NCSXAxis) tmp2)
  36.     (list (nth 1 tmp1))
  37.    )
  38.    (append (mapcar '* ZAxis tmp2) (list (nth 2 tmp1)))
  39.    '(0.0 0.0 0.0 1.0)
  40.     )
  41.     (list (list 1.0 0.0 0.0 (car Orig))
  42.    (list 0.0 1.0 0.0 (cadr Orig))
  43.    (list 0.0 0.0 1.0 (caddr Orig))
  44.    '(0.0 0.0 0.0 1.0)
  45.     )
  46.   )
  47. )
回复 支持 0 反对 1

使用道具 举报

发表于 2009-2-22 12:50 | 显示全部楼层
本帖最后由 作者 于 2009-2-22 12:56:10 编辑

  1. ;; TransNested (gile)
  2. ;; Translates a point coordinates from WCS or UCS to RCS -coordinates system of a
  3. ;; reference (xref or block) whatever its nested level-
  4. ;;
  5. ;; Arguments
  6. ;; pt : the point to translate
  7. ;; rlst : the parents entities list from the deepest nested to the one inserted in
  8. ;;        current space -same as (last (nentsel)) or (last (nentselp))
  9. ;; from to : as with trans function: 0 for WCS, 1 for current UCS, 2 for RCS
  10. (defun TransNested (pt rlst from to)
  11.   (and (= 1 from) (setq pt (trans pt 1 0)))
  12.   (and (= 2 to) (setq rlst (reverse rlst)))
  13.   (and (or (= 2 from) (= 2 to))
  14.        (while rlst
  15. (setq geom (if    (= 2 to)
  16.       (RevRefGeom (car rlst))
  17.       (RefGeom (car rlst))
  18.     )
  19.        rlst (cdr rlst)
  20.        pt   (mapcar '+ (mxv (car geom) pt) (cadr geom))
  21. )
  22.        )
  23.   )
  24.   (if (= 1 to)
  25.     (trans pt 0 1)
  26.     pt
  27.   )
  28. )
  29. ;; RefGeom (gile)
  30. ;; Returns a list which first item is a 3x3 transformation matrix (rotation,
  31. ;; scales, normal) and second item the object insertion point in its parent
  32. ;; (xref, bloc or space)
  33. ;;
  34. ;; Argument : an ename
  35. (defun RefGeom (ename / elst ang norm mat)
  36.   (setq    elst (entget ename)
  37. ang  (cdr (assoc 50 elst))
  38. norm (cdr (assoc 210 elst))
  39.   )
  40.   (list
  41.     (setq mat
  42.    (mxm
  43.      (mapcar (function (lambda (v) (trans v 0 norm T)))
  44.      '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
  45.      )
  46.      (mxm
  47.        (list (list (cos ang) (- (sin ang)) 0.0)
  48.      (list (sin ang) (cos ang) 0.0)
  49.      '(0.0 0.0 1.0)
  50.        )
  51.        (list (list (cdr (assoc 41 elst)) 0.0 0.0)
  52.      (list 0.0 (cdr (assoc 42 elst)) 0.0)
  53.      (list 0.0 0.0 (cdr (assoc 43 elst)))
  54.        )
  55.      )
  56.    )
  57.     )
  58.     (trans
  59.       (mapcar
  60. '-
  61. (cdr (assoc 10 elst))
  62. (mxv mat
  63.      (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 elst)))))
  64. )
  65.       )
  66.       norm
  67.       0
  68.     )
  69.   )
  70. )
  71. ;; RevRefGeom (gile)
  72. ;; RefGeom inverse function
  73. (defun RevRefGeom (ename / entData ang norm mat)
  74.   (setq    entData    (entget ename)
  75. ang    (- (cdr (assoc 50 entData)))
  76. norm    (cdr (assoc 210 entData))
  77.   )
  78.   (list
  79.     (setq mat
  80.    (mxm
  81.      (list (list (/ 1 (cdr (assoc 41 entData))) 0.0 0.0)
  82.    (list 0.0 (/ 1 (cdr (assoc 42 entData))) 0.0)
  83.    (list 0.0 0.0 (/ 1 (cdr (assoc 43 entData))))
  84.      )
  85.      (mxm
  86.        (list (list (cos ang) (- (sin ang)) 0.0)
  87.      (list (sin ang) (cos ang) 0.0)
  88.      '(0.0 0.0 1.0)
  89.        )
  90.        (mapcar (function (lambda (v) (trans v norm 0 T)))
  91.        '((1.0 0.0 0.0) (0.0 1.0 0.0) (0.0 0.0 1.0))
  92.        )
  93.      )
  94.    )
  95.     )
  96.     (mapcar '-
  97.     (cdr (assoc 10 (tblsearch "BLOCK" (cdr (assoc 2 entData)))))
  98.     (mxv mat (trans (cdr (assoc 10 entData)) norm 0))
  99.     )
  100.   )
  101. )
  102. ;;; VXV Returns the dot product of 2 vectors
  103. (defun vxv (v1 v2)
  104.   (apply '+ (mapcar '* v1 v2))
  105. )
  106. ;; TRP Transpose a matrix -Doug Wilson-
  107. (defun trp (m)
  108.   (apply 'mapcar (cons 'list m))
  109. )
  110. ;; MXV Apply a transformation matrix to a vector -Vladimir Nesterovsky-
  111. (defun mxv (m v)
  112.   (mapcar '(lambda (r) (vxv r v)) m)
  113. )
  114. ;; MXM Multiply two matrices -Vladimir Nesterovsky-
  115. (defun mxm (m q)
  116.   (mapcar '(lambda (r) (mxv (trp q) r)) m)
  117. )
这个是gile的。贴此共享。
回复 支持 1 反对 0

使用道具 举报

发表于 2009-2-4 16:00 | 显示全部楼层
对于不等比例的块矩阵好像是无法完成的
 楼主| 发表于 2009-2-4 18:08 | 显示全部楼层

最近我也发现,ET工具里面的块内实体复制Ncopy,也同样存在这个问题,还有就是这个 Ncopy 不单止可以复制块内的实体,几乎所有不是快的也可以复制,另外我在修改这个程序的时候发现 Ncopy 程序有一个 Bug:

若是当前坐标原点出有实体,如直线等经过原点时,在没有关闭捕捉的情况下,执行程序有时会出现错误:

点重合 ; 错误: 函数被取消

这个问题,略加修改就可以避免了。

发表于 2009-2-4 19:28 | 显示全部楼层
 楼主| 发表于 2009-2-4 21:05 | 显示全部楼层
本帖最后由 作者 于 2009-2-4 21:25:03 编辑

caoyin发表于2009-2-4 19:28:00楼主可以参考以下链接的28楼,程序写得不好http://www.mjtd.com/bbs/dispbbs.asp?boardid=3&replyid=118821&id=72404&page=1&skin=0&landlord=0&Star=3

楼上提供的 Ncopy  缺少函数如下:

缺少函数 (LTAX:DOC) BLKS (LTAX:BLKS)

发表于 2009-2-5 18:53 | 显示全部楼层
cadd矩阵是不能直接处理不等比例缩放 的
发表于 2009-2-6 09:16 | 显示全部楼层

回复:(jxphklibin)以下是引用caoyin在2009-2-4 19:...

代码已经修正
发表于 2009-2-20 10:49 | 显示全部楼层

这里有两个很实用的程序以供参考,来自国外。

如果楼主要在深入理解,不妨到www.theswamp.org中去搜索。

 楼主| 发表于 2009-2-20 17:02 | 显示全部楼层

highflybir:

你贴的函数很好,可以适用于任何类型的图块,获取的转换矩阵是正确的!非常感谢!虽然程序较难读懂,但方法正确。

按你新想出来的方法编写的函数,企盼早点出来,呵呵!!!!

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

本版积分规则

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

GMT+8, 2024-5-7 13:54 , Processed in 0.483601 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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