镜像中的变换点
今天这件事让我头痛不已。我有一个例程的请求,该例程应该用2x2dsolids“替换”块内的擦除。原因是我们使用了一个带有抹布的门框来“切割”墙壁&图案填充,而实际上不需要修剪。虽然这对技术绘图很有用,但当我们在做演示时,需要对门下的这些白点进行实体填充(就像每个门都有门槛板一样)。所以我想我可以简单地重新定义块,用一个实体替换覆盖。但是不行,因为阴影区域可以有任何颜色,门的两侧可以有两种不同的颜色。我们现在的想法是在每个块参照之外创建两个单独的实体,并将它们发送到门块的正下方。这很好,甚至适用于缩放和/或动态块-但当它们被镜像时,我似乎无法通过简单的编码正确实现。
经过多次搜索,我发现了这条线索,但这些线索似乎都没有达到我的目的。目前,我正在使用PeterJamtgart的代码进行转换。因为它在非均匀缩放的块上效果最好,所以它的编码绝对最小。问题是,如果我在镜像块上使用它,实体始终处于关闭状态,就好像该块沿着其插入点的X/Y轴镜像回来一样。
我目前(针对Peter的代码)所做的工作是检查XEffectiveScaleFactor的值是否小于0.0(即,查看它是否镜像)。如果是这样,我将围绕Y轴为该块创建一个临时镜像,从该镜像生成点,并使用负Z法线的变换来“反镜像”该点。不幸的是,这使得每个blockreference有4个临时块(因为我想得到4点)。我知道我可以把它全部打包在一个撤销组中,但我觉得它很凌乱。有人知道我怎么摆脱这些临时障碍吗?要么通过来回变换原始数据,要么最好只是通过计算而不影响块?请参见cadtips页面中的修改后的lisp。
一定有一些arb的事情,我现在根本无法理解。也许我只是变老了?真丢脸。。。我没想到我已经过山了! 实际上,现在只需做一个测试,Peter的代码似乎比只使用镜像块还要糟糕。如果块的缩放和旋转不是0.0或180.0度,则点也会关闭。这是我的测试代码:
;****************************************************************************************************
; Written By: Peter Jamtgaard copr 2009
; Function for transforming a point from block object coordinate system to a world coordinate system.
; It handles non uniform scaled blocks
; Syntax:(TranslateWorldToObject <block object> <point in world>)
; Syntax(TranslateObjectToWorld <block object> <point inside block>)
; Returns point in World
;****************************************************************************************************
(defun TranslateObjectToWorld (objBlock ; Block object
lstPointInBlock; Coordinates of point (RELATIVE TO BASE POINT)
; inside the block
/
lstInsertion ; Insertion Point of Block
lstPoint ; List Point of return translate coordinates
lstPointInWorld; Coordinates of point inside the WorldCS
sngTheta ; Rotation angle of Block
varReturn ; Variant return of translate coordinates
)
(if (not objDocument)(setq objDocument (vla-get-activedocument
(vlax-get-acad-object))))
(setq lstInsertion (vlax-get objBlock "insertionpoint")
sngTheta (vla-get-rotation objBlock)
lstPointInBlock (list (* (vla-get-XEffectiveScaleFactor objBlock)
(+ (* (cos sngTheta) (carlstPointInBlock))
(* -1 (sin sngTheta) (cadr lstPointInBlock))))
(* (vla-get-YEffectiveScaleFactor objBlock)
(+ (* (sin sngTheta) (carlstPointInBlock))
(* (cos sngTheta) (cadr lstPointInBlock))))
(* (vla-get-ZEffectiveScaleFactor objBlock)
(caddr lstPointInBlock)))
varReturn (vla-translateCoordinates (vla-get-utility
objDocument)
(vlax-3d-point lstPointInBlock)
acOCS
acWorld
:vlax-false
(vla-get-normal objBlock))
lstPointInWorld (mapcar '+ lstInsertion
(vlax-safearray->list (variant-value varReturn)))
)
)
;****************************************************************************************************
; Written By: Peter Jamtgaard copr 2009
; Function for transforming a point from block object coordinate system to a world coordinate system.
; It handles non uniform scaled blocks
; Syntax:(TranslateWorldToObject <block object> <point in world>)
; Syntax(TranslateObjectToWorld <block object> <point inside block>)
; Returns point in World
;****************************************************************************************************
(defun TranslateObjectToWorld1 (objBlock ; Block object
lstPointInBlock ; Coordinates of point (RELATIVE TO BASE POINT)
; inside the block
/ lstInsertion ; Insertion Point of Block
lstPoint ; List Point of return translate coordinates
lstPointInWorld ; Coordinates of point inside the WorldCS
sngTheta ; Rotation angle of Block
varReturn ; Variant return of translate coordinates
toMirror ; State of mirrored block (by Irn?)
)
(if (not objDocument)
(setq objDocument
(vla-get-activedocument
(vlax-get-acad-object)
)
)
)
;; By Irn?: Check if block's mirrored & create an "unmirrored" block about the Y axis.
(if (setq toMirror (< (vla-get-XEffectiveScaleFactor objBlock) 0.0))
(setq objBlock (vlax-invoke objBlock 'Mirror '(0.0 0.0 0.0) '(0.0 1.0 0.0)))
)
(setq lstInsertion (vlax-get objBlock "insertionpoint")
sngTheta (vla-get-rotation objBlock)
lstPointInBlock (list (* (vla-get-XEffectiveScaleFactor objBlock)
(+ (* (cos sngTheta) (car lstPointInBlock))
(* -1 (sin sngTheta) (cadr lstPointInBlock))
)
)
(* (vla-get-YEffectiveScaleFactor objBlock)
(+ (* (sin sngTheta) (car lstPointInBlock))
(* (cos sngTheta) (cadr lstPointInBlock))
)
)
(* (vla-get-ZEffectiveScaleFactor objBlock)
(caddr lstPointInBlock)
)
)
varReturn (vla-translateCoordinates
(vla-get-utility
objDocument
)
(vlax-3d-point lstPointInBlock)
acOCS
acWorld
:vlax-false
(vla-get-normal objBlock)
)
lstPointInWorld (mapcar '+
lstInsertion
(vlax-safearray->list (variant-value varReturn))
)
)
;; By Irn?: Check if block was "unmirrored"
(if toMirror
(progn
(vla-Delete objBlock) ;Erase the temporary "unmirored" block.
(trans lstPointInWorld '(0.0 0.0 -1.0) 0) ;Translate the "unmirored" point as mirrored about the Y axis
)
lstPointInWorld ;If not mirrored, just send calculated point
)
)
(defun c:Pt2WCS-test (/ ss eo pts pt)
(setq pts '((500.0 0.0 0.0) (0.0 0.0 0.0) (500.0 200.0 0.0)))
(if (and (ssget "_:L" '((0 . "INSERT,*POLY*")))
(setq ss (vla-get-ActiveSelectionset (vla-get-ActiveDocument (vlax-get-acad-object))))
)
(progn
(vlax-for eo ss
(if (eq (vla-get-ObjectName eo) "AcDbBlockReference")
(progn
(setvar "CECOLOR" "1")
(command "_.PLINE")
(foreach pt pts
(command "_None" (TranslateObjectToWorld eo pt))
)
(command "")
(setvar "CECOLOR" "2")
(command "_.PLINE")
(foreach pt pts
(command "_None" (TranslateObjectToWorld1 eo pt))
)
(command "")
(setvar "CECOLOR" "BYLAYER")
)
(vla-Delete eo)
)
)
(vla-Delete ss)
)
)
(princ)
)命令为Pt2WCS测试。
附加的是生成的DWG。我做了一个测试块,上面有一些文字,可以很容易地看到镜像/缩放/旋转的想法。然后,测试代码生成2条多段线。每个都应该从块的右下角到插入点,再到右上角。彼得的代码是用红色绘制的,我修改的代码是用黄色绘制的。
对于非镜像块,Peter的近似正确,但旋转块的方向和比例似乎不正确。在镜像街区,距离“英里”。我的mod在非镜像上也做了同样的事情,但至少在镜像上没有更糟。
图纸1.dwg 试试这个Irne:
使用测试功能:
2主要是根据我的程序在这里、这里和这里开发的。 谢谢李,这似乎很有效。现在,为了弄清楚它实际上做了什么,我知道如何做,而不是简单地重复使用别人的代码!
谢谢Irné,很高兴听到
页:
[1]