AxisAngleRotation3D到四元数给出了意想不到的结果
我正在WPF 3D(使用C#)开发控制器,以便能够使用Move()
和函数轻松移动和旋转ProjectionCamera
。我的控制器将成为Behavior<ProjectionCamera>
,可以连接到ProjectionCamera
。为了初始化控制器,我想通过查看其当前的Up
和Forward
-vectors并将它们与默认摄像机方向(Up = [0 1 0]
,Forward = [0 0 -1]
)进行比较来计算摄像机的当前旋转。换句话说,我想计算一个旋转,将相机默认的方向转换为当前的方向。AxisAngleRotation3D到四元数给出了意想不到的结果
最后,我想表达的旋转作为一个单一的Quaternion
,但作为一个中间步骤我首先计算适当欧拉角旋转的形式ZNZ表示为AxisAngleRotation3D
- 值的,以下的Wikipedia默认定义:
var alphaRotation = CalculateRotation(z, x, N); var betaRotation = CalculateRotation(N, z, Z);
var gammaRotation = CalculateRotation(Z, N, X);
与
CalculateRotation(Vector3D axisOfRotation, Vector3D from, Vector3D to) : AxisAngleRotation3D
欧拉角轮作似乎基于一些单元测试正确计算。但是,当我将这些旋转转换为一个单独的Quaternion
时,生成的Quaternion
表示与欧拉角旋转的差异,我不知道为什么。
这是如何我转换欧拉角为单个四元数:
var rotation = new Quaternion(alphaRotation.Axis, alphaRotation.Angle) *
new Quaternion(betaRotation.Axis, betaRotation.Angle) *
new Quaternion(gammaRotation.Axis, gammaRotation.Angle);
例如,当我初始化ProjectionCamera
与[1 0 0]
一个UpDirection
,这意味着它是被旋转绕其LookDirection
轴旋转90度([0 0 -1]
),计算出的欧拉角旋转被如下:
alphaRotation --> 90 deg. around [0 1 0] betaRotation --> 90 deg. around [0 0 -1]
gammaRotation --> -90 deg. around [1 0 0]
我的测试验证,当按顺序应用,这些旋转将改变默认Up
-vector([0 1 0]
)插入当前的Up
-vector([1 0 0]
),有效地将其旋转90度。围绕着[0 0 -1]
轴。 (手动验证也是合理的。)
但是,当我将计算的QuaternionRotation
应用于默认的Up
-vector时,它将转换为向量[-1 0 0]
,这显然是错误的。我已经硬编码单元测试中的这些结果,并得到了相同的结果:
[TestMethod] public void ConversionTest()
{
var vector = new Vector3D(0, 1, 0);
var alphaRotation = new AxisAngleRotation3D(new Vector3D(0, 1, 0), 90);
var betaRotation = new AxisAngleRotation3D(new Vector3D(0, 0, -1), 90);
var gammaRotation = new AxisAngleRotation3D(new Vector3D(1, 0, 0), -90);
var a = new Quaternion(alphaRotation.Axis, alphaRotation.Angle);
var b = new Quaternion(betaRotation.Axis, betaRotation.Angle);
var c = new Quaternion(gammaRotation.Axis, gammaRotation.Angle);
var combinedRotation = a * b * c;
var x = Apply(vector, alphaRotation, betaRotation, gammaRotation);
var y = Apply(vector, combinedRotation);
}
当你运行上面的测试,你会看到x
给你的期望矢量([1 0 0]
),但y
会有所不同,它应该是完全相同的旋转。
我错过了什么?
回答:
我解决了这个问题。可以看出,个别Quaternions
的乘法顺序应该颠倒过来。因此,将欧拉角(或任何一组旋转角)转换成一个单一的Quaternion
英寸。NET你应该做到以下几点:
var rotation = gammaRotation * betaRotation * alphaRotation;
其中rotation
表示几何应用alphaRotation
,再betaRotation
终于gammaRotation
。我只是希望他们已经记录了这一点,因为订单的含义取决于您正在使用的具体图书馆...
以上是 AxisAngleRotation3D到四元数给出了意想不到的结果 的全部内容, 来源链接: utcz.com/qa/264903.html