使用 System.Numerics.Quaternion 的 3D 旋转
3D Rotation using System.Numerics.Quaternion
这里有人知道如何使用 .net(4.6 及更高版本)旋转 vector3 System.Numerics.Quaternion?
虽然我的数学很差,但我的理解只限于:四元数是 4d "structures",可以在 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 是我最好的猜测,但它不会产生旋转。
首先,四元数主要用于旋转,而不是缩放,绝对不是平移。
class 四元数似乎不是很友好class。我可以根据文档推断如何使用,但我认为它不打算用作旋转的主要工具。
下面是一个使用示例(未测试):
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的平方范数。
作为脚注,这是一个很好的统一版本,我最终得到了:
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
对此的最后更新:
下面使用 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
这里有人知道如何使用 .net(4.6 及更高版本)旋转 vector3 System.Numerics.Quaternion?
虽然我的数学很差,但我的理解只限于:四元数是 4d "structures",可以在 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 是我最好的猜测,但它不会产生旋转。
首先,四元数主要用于旋转,而不是缩放,绝对不是平移。
class 四元数似乎不是很友好class。我可以根据文档推断如何使用,但我认为它不打算用作旋转的主要工具。
下面是一个使用示例(未测试):
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的平方范数。
作为脚注,这是一个很好的统一版本,我最终得到了:
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
对此的最后更新:
下面使用 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