3D Rotation using System.Numerics.Quaternion

一个人想着一个人 提交于 2021-01-29 15:40:18

问题


Anybody here know how to rotate a vector3 using .net(4.6 and up) System.Numerics.Quaternion?

My maths is pretty poor though and my understanding only really goes as far as: quaternions are 4d "structures" that can produce translation, scaling and rotation in 3d.

So I had a play and cannot get any rotation. Doing what seemed obvious : changing the W component of the Quaternion.(angle) then reading the vector produces scaling ?!? Anyone able to help or point me in the right direction for help?

My current rotation (non-quaternion) code (X-axis example)

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

[edit]

    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 is my best guess but it does not produce rotation.


回答1:


First, quaternions are useful mostly for rotations, not scaling and definitely not translations.

The class Quaternion seem to be not a very user friendly class. I can infer how to use based on the documentation, but I think it is not intended to be used as the primary tool for doing rotations.

Here is an example of usage (not tested):

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;

A little bit more efficient version would be:

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

Because the conjugation is only the negation of the vector part of q while the inverse needs to conpute the squared norm of q also.




回答2:


As a footnote this is a nice unified version I ended up with:

  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


来源:https://stackoverflow.com/questions/57185542/3d-rotation-using-system-numerics-quaternion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!