【问题标题】:3D Rotation using System.Numerics.Quaternion使用 System.Numerics.Quaternion 进行 3D 旋转
【发布时间】:2019-07-24 14:40:44
【问题描述】:

这里有人知道如何使用 .net(4.6 及更高版本)System.Numerics.Quaternion 旋转 vector3 吗?

虽然我的数学很差,但我的理解只限于:四元数是 4d 的“结构”,可以在 3d 中产生平移、缩放和旋转。

所以我有一场比赛,无法进行任何轮换。做看起来很明显的事情:改变四元数的 W 分量。(角度)然后读取向量产生缩放?!?任何人都可以提供帮助或为我指出正确的帮助方向吗?

我当前的旋转(非四元数)代码(X 轴示例)

Private Sub Xaxis_rotation(ByVal angle As Double)
        Dim Cangle As Double = Cos(angle)
        Dim Sangle As Double = Sin(angle)
        Parallel.For(1, vertcount, Sub(f As Int32)
                                       Verts(f) -= modelcenter
                                       Verts(f).Y = (Verts(f).Y * Cangle) + (Verts(f).Z * Sangle)
                                       Verts(f).Z = (Verts(f).Z / Cangle) - (Verts(f).Y * Sangle)
                                       Verts(f) += modelcenter
                                   End Sub)
    End Sub

[编辑]

    Dim rotAxis As Vector3 = Vector3.UnitX
    Dim rotangle As Single =  0.785398 '45 degrees as radians
    Dim q As Quaternion = Quaternion.CreateFromAxisAngle(rotAxis, rotangle)
    Dim aVector As Vector3 = *vector to be rotated*

    'rotate
    Dim resultQ As Quaternion = q * Quaternion.CreateFromAxisAngle(aVector, 0) / q

    aVector.X = resultQ.X
    aVector.Y = resultQ.Y
    aVector.Z = resultQ.Z

q*Quaternion.CreateFromAxisAngle(aVector, 0) / q 是我最好的猜测,但它不会产生旋转。

【问题讨论】:

    标签: .net quaternions system.numerics


    【解决方案1】:

    首先,四元数主要用于旋转,而不是缩放,绝对不是平移。

    Quaternion 类似乎不是一个对用户非常友好的类。我可以根据文档推断出如何使用,但我认为它并不打算用作进行旋转的主要工具。

    这是一个使用示例(未测试):

    Vector3 rotAxis = Vector3.UnitX;
    Single rotAngle = 1.5; // in radians
    Quaternion q = Quaternion.CreateFromAxisAngle(rotAxis, 
    rotAngle);
    Vector3 aVector = Vector3.One; //(1,1,1)
    
    // rotate
    Quaternion resultQ = q * (new Quaternion(aVector,0)) / q;
    
    aVector.X = resultQ.X;
    aVector.Y = resultQ.Y;
    aVector.Z = resultQ.Z;
    

    更高效的版本是:

    // rotate
    Quaternion resultQ = q * (new Quaternion(aVector,0)) * Quaternion.Conjugate(q);
    

    因为共轭只是q的向量部分的否定,而逆也需要计算q的平方范数。

    【讨论】:

    • 感谢您的回复。这行代码给了我问题:code' Quaternion resultQ = q * Quaternion(aVector,0) / q; code`
    • 查看对我的原始帖子的编辑,显示我对您的代码的转换。
    • @user5847934 您的编辑错误。试试我编辑的代码。
    【解决方案2】:

    作为脚注,这是我最终得到的一个很好的统一版本:

      Private Sub Nu_rotate(ByVal anglex As Double, ByVal angley As Double, ByVal anglez As Double, ByRef vec0 As Vector3)
        anglex = anglex / 180 * PI
        angley = angley / 180 * PI
        anglez = anglez / 180 * PI
        vec0 -= modelcenter 
        Dim q As Quaternion = Quaternion.CreateFromYawPitchRoll(angley, anglex, anglez)
        Dim resultQ As Quaternion = (q * New Quaternion(vec0, 0)) * Quaternion.Conjugate(q) ' rotation
        vec0.X = resultQ.X
        vec0.Y = resultQ.Y
        vec0.Z = resultQ.Z
        vec0 += modelcenter 
    End Sub
    

    【讨论】:

      【解决方案3】:

      关于此的最终更新:

      下面使用 Vector3.Transform 的代码比以前的方法更快,看起来更准确,定义了 resultq 四元数。

      Public Shared Sub Rotate_point(ByRef Vect As Vector3, CentPoint As Vector3, angles As Vector3)
          Dim Rotator As Quaternion = Quaternion.CreateFromYawPitchRoll(angles.Y, angles.X, angles.Z) 'rotation in radians
          Vect -= CentPoint '---------The point to rotate around.
          Vect = Vector3.Transform(Vect, Rotator)
          Vect += CentPoint
       End Sub
      

      【讨论】:

        猜你喜欢
        • 2013-10-22
        • 1970-01-01
        • 1970-01-01
        • 2021-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-02
        • 1970-01-01
        相关资源
        最近更新 更多