2016-08-02 94 views
1

我正在WPF 3D(使用C#)开发控制器,以便能够使用Move()和函数轻松移动和旋转ProjectionCamera。我的控制器将成为Behavior<ProjectionCamera>,可以连接到ProjectionCamera。为了初始化控制器,我想通过查看其当前的UpForward -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会有所不同,它应该是完全相同的旋转。

我错过了什么?

+0

[旋转顺序问题](https://www.princeton.edu/~naomi/ lecture3.pdf)。 – Sinatr

+0

@Sinatr:是的,我知道轮换的顺序。你是否在我的代码中发现任何错误?因为据我所知,欧拉角必须按顺序(alpha,beta,gamma)应用,并且将这个旋转序列表示为单个四元数,您还必须按此顺序乘以旋转(alpha * beta *伽马)。 –

回答

0

我解决了这个问题。可以看出,个别Quaternions的乘法顺序应该颠倒过来。因此,将欧拉角(或任何一组旋转角)转换成一个单一的Quaternion英寸。NET你应该做到以下几点:

var rotation = gammaRotation * betaRotation * alphaRotation; 

其中rotation表示几何应用alphaRotation,再betaRotation终于gammaRotation。我只是希望他们已经记录了这一点,因为订单的含义取决于您正在使用的具体图书馆...

相关问题