所以我有一艘船,底部有推进器,只能使用它们向前推进。它也可以围绕其中心旋转。它的推进器使其加速,因此它不会以恒定的速度移动。我想做的是告诉它“转移到B点”。
我已经提出了一个解决方案,但它不能很好地工作,并且它不能平稳地旋转,它会急剧移动并且它不会完全到达它应该的位置,所以我必须有一个很大的余地错误。
这是一个正常的问题,如果是这样,有一种“标准”方式吗?这是一个简单的问题吗?我想让它看起来像是在使用玩家拥有的约束(推进器,旋转)来转向自己。这不包括只是从A点到B点。或者是吗?
我很乐意帮助解决这个问题。位置存储在向量中,这是一个2D问题。仅供参考我包括我的解决方案,它基本上是加速船直到旋转它指向点。我认为我对这个想法的实施是个问题:
Vector diff = vector_sub(to_point, pos);
float angle = vector_getangle(diff);
float current_angle = vector_getangle(dir);
float angle_diff = rightrange(angle) - rightrange(current_angle);
float len = vector_getlength(diff);
// "Margin of error"
float margin = 15.0;
// Adjust direction, only if we're not stopping the next thing we do (len <= margin)
if ( len > margin && fabs(angle_diff) > 2.0 )
{
dir = vector_setangle(dir, current_angle + (angle_diff)*delta*(MY_PI) - MY_PI/2);
}
else if ( len > margin )
{
dir = vector_normalize(diff);
}
// accelerate ship (if needed)
acc.x = acc.y = speed;
acc = vector_setangle(acc, vector_getangle(dir));
if ( len <= margin )
{
// Player is within margin of error
}
答案 0 :(得分:2)
如果您不是在寻找一种在线运行的非常通用的解决方案,那么有一个简单的解决方案。我在网上的意思是不断重新计算整个轨迹上的行动。
假设船在开始时处于静止状态,只需将其朝目标点旋转(同时仍处于休息状态)。现在,你的船可以通过加速t
秒,在运动中向后旋转(按照约束为0.5秒)到达目标,然后再减速t秒。如果当前点与目的地之间的距离为d
,那么您需要解决的等式为:
d = 0.5*a*t^2 + 0.5*a*t + 0.5*a*t^2
第一个术语是加速时行进的距离。第二个术语是旋转时行进的距离(v*t_rot
,v=a*t
,t_rot=0.5
)。最后一项是减速时行驶的距离。解决t
的上述问题,你就有了自己的轨迹。
如果船在开始时移动,我会先停止它(只是在其速度矢量的相反方向旋转,然后减速直到静止)。现在我们知道如何到达目的地。
离线轨迹计算的问题是它不是很准确。你很有可能最终会在目标附近,但不会完全位于目标附近。
让问题变得更有趣:船只在没有加速的情况下无法旋转。让我们称这个加速度向量a_r
,一个与船的方向成一定角度的向量(有点像在后面有一个角度的推进器)。您现在的任务是旋转船舶并沿着这样的方向加速,使得垂直于连接当前位置和目标位置的矢量的速度分量被抵消。我没有尝试离线计算向量,而是采用在线方法。
最简单的方法是在每个时间间隔添加以下算法:
这会振动一下,我怀疑它会在一段时间后稳定下来。我必须承认,我不知道如何让它停在目的地。
最后的方法是模拟船舶的动力学,并尝试将其线性化。它将是一个非线性系统,因此第二步将是必要的。然后将模型转换为离散时间系统。最后应用控制规则使其达到目标点。为此,您可以将状态空间从位置和速度更改为位置错误和(可能)速度错误,最后添加一个调节控制(一个控制循环,它采用当前状态,并生成一个输入,使得状态变量将接近于零。
最后一个在数学室中相当困难,你可能需要稍微研究一下控制工程。但是,你会得到比上述简单算法更好的结果 - 诚然,这些算法甚至可能无法正常工作。此外,您现在可以应用各种优化规则:最小化达到目标的时间,最小化燃料消耗,最小化行进距离等。