4.3 找到对应一个方向的旋转角
问题
通过绘制模型前设置世界矩阵(见前一个教程)时,你可以在场景的任意位置放置模型。当你将模型从A点移至B点,你需要确保它转向正确的方向。
这个旋转角通常通过一个自然的方式获取,例如,当处理一个包含旋转的世界矩阵。但是,如果你只是存储模型的前一个位置和当前位置的方法移动模型的话,那么必须手动旋转这个模型。
解决方案
你需要首先计算模型运动的方向。从这个方向的X轴和Z轴开始,很容易找到这个角度。
工作原理
给定一个方向,你想知道需要旋转模型多少角度才能让它指向这个方向。给定如图4-8右边所示的方向,你想找到这个方向与Z轴的夹角。
如果你还记得三角形的基本知识那么这个解决方案是很简单的。给定如图4-8左边所示的三角形,你可以通过计算S除以L的反正切值(atan)得到a角,对于右图的情况,你可以通过计算方向的X分量除以Z分量的反正切值获取旋转角度。
图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 阅读次数:6048