我知道这是一个古老的问题,但是我认为到目前为止给出的答案中缺少一些东西。在最初的问题中,导弹(或任何其他物体)被告知要加速向目标位置前进。有几个答案指出这是错误的,您应该在以后的某个时间加快目标速度。这更好,但仍然是错误的。
您真正想做的不是加速朝目标前进,而是朝着目标前进。考虑这一点的方法是将所需的速度指向目标(或目标位置的投影),然后找出最适合的加速度(给定任何限制,即导弹可能无法加速)直接相反)以达到您想要的速度(记住速度是一个向量)。
这是我今天早上实施的一个有效示例,以我在体育模拟游戏中针对玩家AI的情况为例,该玩家试图追赶对手。该运动由标准的“踢球漂移”模型控制,该模型在时间步的开始处应用加速度以更新速度,然后对象在该时间步的持续时间内以该速度漂移。
我会发布它的派生词,但我发现此网站上不支持数学标记。!您只需要相信这是最佳解决方案,因为我对加速度方向没有限制,而对于导弹类型的对象则不是这样,因此需要一些额外的约束。
代码在python中,但是在任何语言背景下均应可读。为简单起见,我假设每个时间步长为1,并以适当的单位表示速度和加速度以反映这一点。
self.x = # current x co-ordinate
self.y = # current y co-ordinate
self.angle = # current angle of motion
self.current_speed = # current magnitude of the velocity
self.acc # Maximum acceleration player can exert on themselves
target_x = # x co-ordinate of target position or projection of it
target_y = # y co-ordinate of target position or projection of it
vx = self.current_speed * math.cos(self.angle) # current velocity x component
vy = self.current_speed * math.sin(self.angle) # current velocity y component
# Find best direction to accelerate
acc_angle = math.atan2(self.x + vx - target_x,self.y + vy - target_y)
请注意,atan2(a,b)函数计算a / b的反正切值,但要确保角度位于圆的正确象限中,这需要知道a和b的符号。
就我而言,一旦获得加速度,便应用该加速度来更新速度
vx_new = vx + self.acc * math.cos(acc_angle)
vy_new = vy + self.acc * math.sin(acc_angle)
self.current_speed = math.sqrt( vx_new**2 + vy_new**2)
self.angle = math.atan2(vy_new,vx_new)
我还会根据玩家的最大速度检查新速度,并以此为上限。如果是导弹,汽车或具有最大转弯速度(单位为每跳的度数)的物体,您可以简单地查看当前运动角度与计算得出的理想值之间的关系,如果此变化幅度大于允许值,只需将角度更改为尽可能地走向理想。
对于任何对此推导感兴趣的人,我都会在进行了最后一步之后写下玩家与目标之间的距离,包括初始位置,速度,加速速率和加速角,然后针对加速角取导数。将该值设置为零可找到时间步后玩家目标距离的最小值,该最小值是加速度角的函数,这正是我们想要知道的。有趣的是,即使加速度最初是方程式中的,它也抵消了使最佳方向独立于您实际能够加速的速度。