MJLM 发表于 2022-7-5 16:00:07

获取实体i的点

我在一个块内有一个圆,这个块被插入到一个图形中。我想得到WCS中圆心的坐标。显然,圆心不是插入点。
 
我发现“nentselp”用trans进行转换。矩阵,但要求我给出一个我没有的点(用户输入是不可能的),所以我不为我工作。然而,块的所有其他数据是已知的。
 
我用下面这条线找到了圆心
 
(setq ptz (cdr (assoc 10 (entget (cadr (getblkitems ent))))))
 
“getblkitems”返回列表中的所有实体名称(有人善意地在论坛中发布),我知道第二个实体(因此上面的cadr)是圆。
 
但现在的问题是,我没有trans。矩阵以获取WCS中的点。有没有关于如何将其转化的想法,或者有没有关于不同方法的想法?
 
非常感谢。

Lee Mac 发表于 2022-7-5 16:09:10

下面是一个示例:
(defun blockreferencecirclecenter ( ref / cen ent enx )
   (setq ent (tblobjname "block" (cdr (assoc 2 (entget ref)))))
   (while
       (and
         (null cen)
         (setq ent (entnext ent))
         (setq enx (entgetent))
       )
       (if (= "CIRCLE" (cdr (assoc 0 enx)))
         (setq cen (trans (cdr (assoc 10 enx)) (cdr (assoc 210 enx)) 0))
       )
   )
   (if cen (apply '(lambda ( mat vec ) (mapcar '+ (mxv mat cen) vec)) (refgeom ref)))
)

;; RefGeom (gile)
;; Returns a list whose first item is a 3x3 transformation matrix and
;; second item the object insertion point in its parent (xref, block or space)

(defun refgeom ( ent / ang enx mat ocs )
   (setq enx (entget ent)
         ang (cdr (assoc 050 enx))
         ocs (cdr (assoc 210 enx))
   )
   (list
       (setq mat
         (mxm
               (mapcar '(lambda ( v ) (trans v 0 ocs t))
                  '(
                     (1.0 0.0 0.0)
                     (0.0 1.0 0.0)
                     (0.0 0.0 1.0)
                   )
               )
               (mxm
                   (list
                     (list (cos ang) (- (sin ang)) 0.0)
                     (list (sin ang) (cos ang)   0.0)
                      '(0.0 0.0 1.0)
                   )
                   (list
                     (list (cdr (assoc 41 enx)) 0.0 0.0)
                     (list 0.0 (cdr (assoc 42 enx)) 0.0)
                     (list 0.0 0.0 (cdr (assoc 43 enx)))
                   )
               )
         )
       )
       (mapcar '- (trans (cdr (assoc 10 enx)) ocs 0)
         (mxv mat (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx))))))
       )
   )
)

;; Matrix Transpose-Doug Wilson
;; Args: m - nxn matrix

(defun trp ( m )
   (apply 'mapcar (cons 'list m))
)

;; Matrix x Matrix-Vladimir Nesterovsky
;; Args: m,n - nxn matrices

(defun mxm ( m n )
   ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
)

;; 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 ( / cen ent )
   (if (setq ent (car (entsel)))
       (if (= "INSERT" (cdr (assoc 0 (entget ent))))
         (if (setq cen (blockreferencecirclecenter ent))
               (entmake (list '(0 . "POINT") (cons 10 cen) (cons 210 (trans '(0 0 1) 1 0 t))))
               (princ "\nNo circle found in block definition.")
         )
         (princ "\nObject is not a block.")
       )
       (princ "\nNo object selected.")
   )
   (princ)
)

lrm 发表于 2022-7-5 16:11:28

 
如果您知道块坐标系中点的坐标(以下示例中的POC),或者可以获得它们,则可以将点的齐次坐标乘以矩阵。我的矩阵乘法函数没有其他函数那么优雅,但它可以工作。
 
(defun c:tt (/)
(setq pOCS '(1.11 2.22 3.33)); coordinates in Object Cor. Sys
(setq M (cadr (cdr (nentsel)) )) ; block 4 x 3 matrix

(setq pWCS (transform pOCS M)) ; coordinates in WCS
(princ pwcs)
(princ)
)

(defun transform (a HTM / transpt)        ;Coordinate transformation via matrix multiplication
                                ; a = point (3 coordinates)
                                ; HTM = homogeneous transformation matrix (3 x 4)
(setq aH (append a '(1.0)))                ; aH = homogeneous point in local coordinates (1 x 4)
(setq        transpt
(list
   (+                                ; transpt = list of x, y, z coordinates
   (* (nth 0 aH) (nth 0 (nth 0 HTM)))
   (* (nth 1 aH) (nth 0 (nth 1 HTM)))
   (* (nth 2 aH) (nth 0 (nth 2 HTM)))
   (* (nth 3 aH) (nth 0 (nth 3 HTM)))
   )
   (+
   (* (nth 0 aH) (nth 1 (nth 0 HTM)))
   (* (nth 1 aH) (nth 1 (nth 1 HTM)))
   (* (nth 2 aH) (nth 1 (nth 2 HTM)))
   (* (nth 3 aH) (nth 1 (nth 3 HTM)))
   )
   (+
   (* (nth 0 aH) (nth 2 (nth 0 HTM)))
   (* (nth 1 aH) (nth 2 (nth 1 HTM)))
   (* (nth 2 aH) (nth 2 (nth 2 HTM)))
   (* (nth 3 aH) (nth 2 (nth 3 HTM)))
   )
)
)
(setq transpt (list (nth 0 transpt) (nth 1 transpt) (nth 2 transpt)))
)                                        ;end transform
 
可能有一种方法可以使用trans函数来实现这一点。
 
LRM公司

Jef! 发表于 2022-7-5 16:14:10

@李。介意吹。
 
看起来很长。另一个灵感来源于李的另一件艺术作品。
(defun c:test ( / ent sel lst)
   (if (and (cdddr (setq sel (nentselp)))
            (= "CIRCLE" (cdr (assoc 0 (setq lst (entget (car sel))))))
            (setq ent (entmakex (list '(0 . "POINT") (cons 10 (trans (cdr (assoc 10 lst)) (cdr (assoc 210 lst)) 0)) (cons 210 (trans '(0 0 1) 1 0 t)))))
       )
       (progn
         (vla-transformby (vlax-ename->vla-object ent) (vlax-tmatrix (caddr sel)))
         (vla-regen (vla-get-activedocument (vlax-get-acad-object)) acallviewports)
       )
   )
   (princ)
)

Lee Mac 发表于 2022-7-5 16:21:56

 
干杯,杰夫!
 
 
感谢分享,但正如OP所说:
 
 
...否则我也会建议使用nentsel(p)

Jef! 发表于 2022-7-5 16:23:55

啊!虽然在你的代码(c:测试)中,你可以用任何ename替换(car)(entsel),但我不能以任何方式将插入的ename馈送到我的替代方案中的(entselp)以删除用户输入,对吗?我懂了。
 
我正要在我的阿凡达上添加一些小轮子,我想我会推迟一段时间,让我的装备保持原样!
 
干杯

Grrr 发表于 2022-7-5 16:31:01

只是出于好奇:
是否可以获得块引用的矩阵,而不选择它(使用nentselp),而是使用ename/vla对象?
 
一、 e.编写一个函数来翻译依赖于块定义内部的提供点,并提供块引用(当然):
 
(foo BlockReference PtInsideBlkDef) -> PtInWCS
 
甚至可以翻译整个点列表(这可能更有效):
 
(foo BlockReference PtListInsideBlkDef) -> PtListInWCS
 
 
我有一个关于获取嵌套直线/多段线线段的端点的旧想法,即通过拾取嵌套直线/多段线线段来对齐两个块参照。
但我被这个transformby任务困住了。
 
当然,我的想法的概念可能会使用(nentselp)选项,但我的问题是我文章的第二行。
 
 
你甚至可以这样通过嵌套块参照进行翻译:
(foo BlockReferenceA (foo BlockReferenceB (foo BlockReferenceC PtListInsideBlkDef)))
如果我的问题的答案是“是”。

Lee Mac 发表于 2022-7-5 16:35:22

 
确切地
 
 
独轮车?
 
 
是的-请参阅此帖子。
 
 
你确实可以。

Grrr 发表于 2022-7-5 16:37:18

谢谢李我想我会开始更仔细地研究这些代码。

MJLM 发表于 2022-7-5 16:46:00

再次感谢李。
页: [1] 2
查看完整版本: 获取实体i的点