silveroak 发表于 2008-10-27 09:38:54

读取 3D 旋转属性

您好,
我有一段代码,可以读回图形中块引用的旋转属性。现在我需要能够在所有三个平面上观察块参照的旋转。在WCS中,我始终将旋转属性理解为围绕XY平面中的插入点。如何读取相对于插入点的XZ和YZ旋转?
**** Hidden Message *****

Bryco 发表于 2008-10-27 10:22:35

如果你能跟上大学入学考试,我可以张贴其余的代码代码0]

silveroak 发表于 2008-10-27 12:19:57

Bryco,我们从BlocRefMatrix回来的4x4,是从0,0,0旋转和平移吗?如果您发布其余功能,那就太好了。从那里
,我所要做的就是以相同的方式定向许多块引用,您能否指出我或发布将旋转组件应用于块引用的源?
或者可以应用4x4转换的东西也可以工作,我可以将我的块引用到原点,并且它们不会被旋转。
我对所有这些非常陌生,不知道从AutoCAD开始。在工具中,我正在处理我们的块和位置始终是3d的,但只有xy旋转曾经被使用过,这在属性中很方便。我对CAD中3D转换的了解是0,理论几乎被遗忘了。 如果我能从您的代码的其余部分获得转换,然后有一种方法可以将其应用于其他内容,那么我将很好地恢复!
谢谢!

silveroak 发表于 2008-10-27 17:06:19

我正在阅读文档并意识到我们有TransformBy,
如上所述,我需要以同样的方式定向未旋转的块引用。它们的插入点应该保持在原位。
如果我从BlockRefMatrix中获取4x4,将最后一行中的翻译xyz信息设置为0,并将TransformBy所需的块与它一起设置,它会导致所需的相同方向吗?请让我知道我是否在正确的轨道上。

Bryco 发表于 2008-10-27 22:27:08

我仍然不太清楚你在做什么,但剩下的就在这里。
是的,这会在x、y和z方向上产生变换和旋转
如果你立即向上(ctrl+G),你会看到矩阵打印出来(我喜欢打印出来的方式)。
我想你会找到你需要的,我不知道如何将它们直接转换成角度,因为顺序很重要
Option Explicit
Sub TEST()
    Dim b As AcadBlockReference, ent As AcadEntity, V, m
    ThisDrawing.Utility.GetEntity ent, V, "Pick"
    If ent Is Nothing Then Exit Sub
    If Not TypeOf ent Is AcadBlockReference Then Exit Sub
    Set b = ent
    m = BlockRefMatrix(b)
    PrintM m
   
End Sub
Function RotZ(ang As Double) As Variant
   'Rotate by an angle around the z axis
    Dim m
    Dim CosAng As Double, sinAng As Double
   
    CosAng = Cos(ang): sinAng = Sin(ang)
    m = IDMatrix
    m(0, 0) = CosAng
    m(0, 1) = -sinAng
    m(1, 0) = sinAng
    m(1, 1) = CosAng
      
    RotZ = m
End Function
Function M4xM4(M1, M2) As Variant
    'Matrix x matrix
    Dim m(3, 3) As Double
    Dim I As Integer, j As Integer
    Dim k As Integer
    Dim Sum As Double
   
    For I = 0 To 3
      For j = 0 To 3
            For k = 0 To 3
                Sum = Sum + M1(k, j) * M2(I, k)
            Next k
            m(I, j) = Sum
            Sum = 0
      Next j
    Next I
    M4xM4 = m
   
End Function
Function NormaliseVector(V As Variant) As Variant
    Dim Unit As Double
    Dim Vn(2) As Double
    Unit = Sqr(V(0) * V(0) + V(1) * V(1) + V(2) * V(2))
    Vn(0) = V(0) / Unit: Vn(1) = V(1) / Unit: Vn(2) = V(2) / Unit
    NormaliseVector = Vn
End Function
Function Crossproduct(a, b) As Variant
    Dim Ax As Double, Ay As Double, Az As Double
    Dim Bx As Double, By As Double, Bz As Double
    Dim Unit As Double
    Dim c(2) As Double
    'get CrossProduct
    Ax = a(0): Ay = a(1): Az = a(2)
    Bx = b(0): By = b(1): Bz = b(2)
   
    c(0) = Ay * Bz - Az * By
    c(1) = Az * Bx - Ax * Bz
    c(2) = Ax * By - Ay * Bx
   
    'Convert to unit normal
    Unit = Sqr(c(0) * c(0) + c(1) * c(1) + c(2) * c(2))
    c(0) = c(0) / Unit: c(1) = c(1) / Unit: c(2) = c(2) / Unit
    Crossproduct = c
End Function
Function IDMatrix()
    Dim m(3, 3) As Double
    Dim I As Integer, j As Integer
    m(0, 0) = 1
    m(1, 1) = 1
    m(2, 2) = 1
    m(3, 3) = 1
    IDMatrix = m
   
End Function
Sub PrintM(m)
    Dim I As Integer
    Dim j As Integer
    Debug.Print
    If UBound(m, 2) > 3 Then
      For I = 0 To 3
             Debug.Print m(I, 0), m(I, 1), m(I, 2), m(I, 3), m(I, 4), m(I, 5), m(I, 6), m(I, 7)
      Next
    Else
      For I = 0 To 3
             Debug.Print m(I, 0), m(I, 1), m(I, 2), m(I, 3)
      Next
    End If
   
End Sub

silveroak 发表于 2008-10-28 08:50:56

再次感谢您,Bryco,
您的代码对我来说是一个很好的起点。我将不得不将其转换为C#,因为这是我用来驱动AutoCAD的,但从那里我将看到如何使用矩阵
对我来说,最重要的部分是将一个块的方向复制到另一个块。我在考虑提取角度并应用旋转3D,但正如你所说,我不知道顺序。通过使用矩阵的旋转分量并通过TransformBy将其应用于另一个块参照,我可能也能实现同样的效果。

Bryco 发表于 2008-10-28 09:33:39

在C#中,矩阵非常容易,如果你在代码红色的净部分发布代码的旋转部分,你应该得到一些帮助

silveroak 发表于 2008-10-29 21:33:35

在转换为C#并尝试使用TransformBy应用它之后,我终于让它工作,事实证明,
必须将生成的块矩阵转置或重新构建列优先才能使用TransformBy。 如果应用于0,0,0的未旋转块,它将完全重新创建块的位置和方向。
如果它没有被转置,它将做最奇怪的事情,包括疯狂的缩放和使块消失(也许变得很小,不确定):ugly:
当我意识到AutoCAD中的转换矩阵示例帮助在底部行中有未使用的0,0,0时,我注意到了差异,而不是测试输出中最右边的。
我想知道为什么会这样,这个代码会像这样构建它(只是好奇心)?

Bryco 发表于 2008-10-29 23:06:42

我个人讨厌在cad中构建matricies的方式,我提供的代码对我来说是有意义的。
我通过回溯跟踪getsubentity提供的cad矩阵发现了这一点,它为您提供了将子实体从blockref放回0,0 blockdef的矩阵。这与我想要的180度,所以你可能需要一个逆和转置。
页: [1]
查看完整版本: 读取 3D 旋转属性