2012-01-18 43 views
0

這可能更像是一個數學學科領域,但我希望這很容易讓其他一些開發人員知道。創建一個關於前向矢量的旋轉

情況:我有飛機遊戲。我需要相對於飛機的方向進行俯仰,偏航和滾轉(繞x,y,z旋轉)平面。

問題:我可以讓平面模型旋轉,但旋轉對模型來說是全局的。例如,當飛機面向前方時,應用CreateRotationZ()可以正常工作,但如果模型朝上(90度間距),則應用CreateRotationZ()不會導致飛機滾轉(相對於飛機方向),它導致它偏航。

+0

你知道有'CreateRotationX'和'CreateRotationY'嗎?然而,當飛機處於不同的角度時,會有更復雜的數學。但它將是3種方法的組合。 – anothershrubery 2012-01-18 15:44:01

+0

是,CreateRotationZ(偏航),CreateRotationX(間距)和CreateRotationY(滾動)。這些不工作,雖然他們旋轉,而不考慮在飛機上的方向解釋。 我已經但是非常接近使用: 四元腐爛= Quaternion.CreateFromAxisAngle(新的Vector3(0,0,1),滾動)* Quaternion.CreateFromAxisAngle(新的Vector3(1,0,0),間距)*四元.CreateFromAxisAngle(new Vector3(0,1,0),Yaw); Airframe.Orientation = Matrix.CreateFromQuaternion(rot); 如果您將飛機向右滾動,則正確應用俯仰運作,但偏航不會。非常令人沮喪 – Neovivacity 2012-01-18 17:03:28

+0

是的,您需要將座標軸定位到您的船上,而不是世界座標軸。您的船舶的旋轉矩陣將有訪問者獲得(前進,後退,左,右,上,下),您可以旋轉這些向量。 – 2012-01-19 19:49:25

回答

1

對你的對象/實體/船舶的位置(的Vector3)和旋轉(矩陣),然後你可以使用下面的代碼示例中的任何局部軸移動或旋轉。

例如,要彙總飛機45度(這是關於你問的是正向矢量旋轉):

Entity plane = new Entity(); 
plane.Roll(MathHelper.PiOver4); 

或瀝青滾飛機90度:

plane.Pitch(MathHelper.PiOver2);  

而這裏的代碼示例

public class Entity 
{ 
    Vector3 position = Vector3.Zero; 
    Matrix rotation = Matrix.Identity; 

    public void Yaw(float amount) 
    { 
     this.rotation *= Matrix.CreateFromAxisAngle(this.rotation.Up, amount); 
    } 

    public void YawAroundWorldUp(float amount) 
    { 
     this.rotation *= Matrix.CreateRotationY(amount); 
    } 

    public void Pitch(float amount) 
    { 
     this.rotation *= Matrix.CreateFromAxisAngle(this.rotation.Right, amount); 
    } 

    // This is the specific method you were asking for in the question title 
    public void Roll(float amount) 
    { 
     this.rotation *= Matrix.CreateFromAxisAngle(this.rotation.Forward, amount); 
    } 

    public void Strafe(float amount) 
    { 
     this.position += this.rotation.Right * amount; 
    } 

    public void GoForward(float amount) 
    { 
     this.position += this.rotation.Forward * amount; 
    } 

    public void Jump(float amount) 
    { 
     this.position += this.rotation.Up * amount; 
    } 

    public void Rise(float amount) 
    { 
     this.position += Vector3.Up * amount; 
    } 
} 

如果您想要平穩移動,您希望以非常小的增量使用它們,並在計算中使用所用時間的amount

+0

+1這是個好建議。我唯一需要注意的是,無論何時使用CreateFromAxisAngle,軸(在你的Pitch()方法中,this.rotation.Right)都應該在使用之前進行標準化。如果你讓這個幻燈片,浮點錯誤將複合(不積累,但複合),你的矩陣會相對較快地扭曲。但是,如果您對軸線進行了歸一化處理,則該錯誤僅會累積,並且需要幾小時或幾天才能顯着扭曲,這通常是可以接受的。 – 2012-01-19 13:54:48

+0

只要您不手動使用Matrix自身(手動更改其值而不是使用所提供的功能),XNA爲您提供的向量在您訪問Matrix類時總是會進行規範化。但是你提出了一個很好的觀點,我想我會編寫一個單元測試,它可以旋轉關於不同座標軸的Matrix,並且在每次旋轉檢查已知值後,這應該讓我看看它是否漂移或扭曲。 – 2012-01-19 14:49:19

0

使用Matrix.CreateWorld(),更適合你想要的, 參數是位置,正向矢量和向上矢量。

http://msdn.microsoft.com/en-us/library/bb975261.aspx

+0

你將如何去實現它, 在一個側面說明中,我只是找到了答案,很明顯,很多開發人員面對他們,直到他們看到光明。 跟蹤全球旋轉是壞事。每次更新只需輕微更新方向即可。當我的8小時等待在我的問題上發佈我自己的答案時,明天就會有完整的解決方案,哈哈。 – Neovivacity 2012-01-18 21:03:17