2016-08-02 95 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。我只是希望他們已經記錄了這一點,因爲訂單的含義取決於您正在使用的具體圖書館...

相關問題