4.3 找到对应一个方向的旋转角

问题

通过绘制模型前设置世界矩阵(见前一个教程)时,你可以在场景的任意位置放置模型。当你将模型从A点移至B点,你需要确保它转向正确的方向。

这个旋转角通常通过一个自然的方式获取,例如,当处理一个包含旋转的世界矩阵。但是,如果你只是存储模型的前一个位置和当前位置的方法移动模型的话,那么必须手动旋转这个模型。

解决方案

你需要首先计算模型运动的方向。从这个方向的X轴和Z轴开始,很容易找到这个角度。

工作原理

给定一个方向,你想知道需要旋转模型多少角度才能让它指向这个方向。给定如图4-8右边所示的方向,你想找到这个方向与Z轴的夹角。

如果你还记得三角形的基本知识那么这个解决方案是很简单的。给定如图4-8左边所示的三角形,你可以通过计算S除以L的反正切值(atan)得到a角,对于右图的情况,你可以通过计算方向的X分量除以Z分量的反正切值获取旋转角度。

图4-8

图4-8 计算偏离给定方向的旋转角

atan方法返回的值在+90度和–90度之间(当两个负数相除时,负号会丢失)。

幸运的是,.NET Framework还提供了Atan2方法,这个方法可以让你分别提供X和Z值,返回在–180至180度范围内的值,让旋转角定义在完整的一个圆周内。

下面的简单方法计算对应模型当前位置和前一个位置的旋转角:

private float CalculateRotation(Vector3 oldPos, Vector3 newPos, float lastRot)
{
    Vector3 direction = newPos - oldPos; 
    if ((direction.X == 0) &&(direction.Z == 0)) 
        return lastRot; 
    else 
        return (float)Math.Atan2(direction.X,direction.Z); 
} 

首先你找到旧位置指向新位置的方向用于计算对应旋转角。如果模型停止移动或垂直移动,这个方向的X和Z都是0,Atan2方法会返回一个无用的值,这时要返回上次的旋转值,这样不动的模型会保持它的旋转值。

用法

你应该使用这个计算出的旋转角创建一个绕向上的Y轴的旋转,这样模型的前方就会朝向运动的方向。当创建世界矩阵时,你应该首先平移模型然后进行旋转。这意味着你应该在矩阵乘法中将旋转放置在平移的左边(见教材4-2)。看一下下面的例子,模型最后的位置存储在position变量中,而angle变量是由CalculateRotation方法计算得到的:

worldMatrix = Matrix.CreateTranslation(position); 
worldMatrix = Matrix.CreateRotationY(angle) * worldMatrix; 
worldMatrix = Matrix.CreateScale(0.005f) * worldMatrix; 

在本例中,首先模型坐标被移动到模型中心的最终位置,然后施加绕Y轴的旋转,之后使模型变小。

代码

你可以在前面看到CalculateRotation方法的代码。

程序截图


发布时间:2009/6/5 上午7:54:31  阅读次数:5613

2006 - 2024,推荐分辨率 1024*768 以上,推荐浏览器 Chrome、Edge 等现代浏览器,截止 2021 年 12 月 5 日的访问次数:1872 万 9823 站长邮箱

沪 ICP 备 18037240 号-1

沪公网安备 31011002002865 号