2012-01-18 81 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