如何在飞行模拟器中计算上矢量



我正在为OpenGL ES 2.0编写3D应用程序,用户可以在其中设置路径并飞越某些地形。它基本上是一个轨道上的飞行模拟器。

路径由从样条曲线创建的一系列点定义。每个时间片,我使用插值来推进当前位置,即,我在p0到p1之间插值,然后当我到达p1时,我在p1和p2之间插值,最后从pN返回到p0。

我用类似于gluLookAt的东西创建了一个视图矩阵。眼睛坐标是当前位置,视线是路径上的下一个位置和向上(0,0,1)。因此,相机朝着它下一个飞行的地方看,Z指向天空。

但现在我想在转弯时"靠岸"。即向上矢量不一定是直接向上的,而是基于转动率的变化。我知道我现在的方向和上一个方向,所以我可以增加或减少银行的一些金额。点积会告诉我转弯的角度,叉积会告诉我们是向左还是向右。我可以保持一个倾斜角度,并将其保持在-/+70度的范围内,适当地递增或递减。

我认为这是正确的方法,但我可能会花很长时间来实现它,以发现它不是。

我走在正确的轨道上了吗?有没有样本可以证明我正在尝试做什么?

既然你有一架在正常条件下飞行的光滑飞机,你就不需要太多。。。你的方法几乎是正确的,看起来会很自然。您所需要的只是3个顺序点a、B、C:cross = cross(A-B, C-B)之间的叉积。现在,cross是使平面围绕"正向"向量旋转所需的向量:自然地,平面的向上向量通常是(-万有引力)(0,0,1),点B中的正向向量是C-B(如果不需要插值),现在"侧"向量是side = normalized(cross(forward, up)),这是使用银行的地方:side = side + cross*planeCorrectionParameter,然后是up = cross(normalized(side), normalized(forward))。"planeCorrectionParameter"是一个你应该玩的参数,实际上它代表了一些参数的组合,如机翼和船体的尺寸、空气密度、重力、速度、质量…

请注意,上面的一些交叉操作可能需要按参数顺序进行交换(cross(a,b)应该是cross(b,a)),所以用它来处理一下。

您的方法听起来是正确的,但看起来会不自然。举个例子,一条看起来像sin函数的路径:当平面实际上向右移动时,它可能会向左"移动"。

我可以提两种解决你问题的方法。首先,可以获取样条曲线的导数。我假设你的样条曲线是一个返回点(x, y, z)f(t)函数。参数曲线的导数是指向旋转中心的向量:它将指向圆形路径的中心。

使用上述方法需要注意的几点是:直线的导数为0,向量也将为0,因此必须手动固定上向量。此外,您可能需要修复这个向量,这样它就不会倒置。

这比你的方法有效而且看起来更好。但对于某些曲线来说,它看起来仍然不自然。我能提到的最好的方法是四元数插值,比如Slerp。在曲线的每个点上,也有一个"右"向量:指向平面右侧的向量。根据曲线和该向量,可以计算出该点的向上向量。然后,使用四元数插值来沿曲线插值向上向量。

如果位置和旋转仅取决于样条曲线的曲率,最简单的方法是对三维样条曲线进行数值微分(您将有两个导数,一个用于垂直分量,一个为水平分量)。你的向上和侧面将是切线的法线。

最新更新