二维弹丸轨迹计算半径

时间:2017-03-10 00:35:43

标签: geometry 2d game-physics trigonometry

我有一个带有角色(Al)的2D游戏试图"保存"来自NPC(Ho)的另一个角色(Bu)。

AlBu具有恒定的速度(莎莉静止不动)。

我需要弄清楚如何计算Al应该定位到哪个点以便停止Bu

我在阅读this tutorial后能够对此进行编程。我将部分pylab代码转换为numpy

def interception(Al, Bu, Ho, Sa, Sb):
    """ Returns ``(t_C, C)`` if A can catch B, before B 
    reaches H. Otherwise, returns ``None``. """
    A = np.array((Al["x"],Al["y"]))
    B = np.array((Bu["x"],Bu["y"]))
    H = np.array((Ho["x"],Ho["y"]))
    AB, AH, BH = np.linalg.norm(A-B), np.linalg.norm(A-H), np.linalg.norm(B-H)
    #if Ho["id"] =="1":
    #    print("AB=%s BH=%s"%(AB,BH), file=sys.stderr)
    if AB*BH == 0:
        return None, None
    sin_b = np.linalg.det(np.array((A-B,H-B))) / (AB*BH)
    sin_a = (Sb / Sa) * sin_b
    if abs(sin_a) > 1 :
        print("B moves too fast to be ever caught !", file=sys.stderr)
        return None, None
    else:
        sin_c = ( sin_a * math.sqrt(1 - sin_b**2)
                  + sin_b * math.sqrt(1 - sin_a**2) )
        BC = AB * (sin_a / sin_c)
        #if Ho["id"] ==1:
            #print(BC-BH, file=sys.stderr)
        if BC > BH:
           # print("B reaches H before interception by A !", BC,BH, file=sys.stderr)
            return None, None
        else:
            #print("A intercepted B !")
            t_C = BC / Sb
            C = B + BC * (H-B)/ BH
            return t_C, C

这很好用,但问题是我想弄清楚。我想调整此interception函数以获得另一个参数Al_radius。您看,Al有枪,当Bu的范围为Al_radius时,Al可以开枪Bu

我非常确定,根据Al的范围,他的目标位置可能会发生变化(例如,侧翼可能更快,而不是直接朝{{1}之间的路径前进}和Bu)。

1 个答案:

答案 0 :(得分:0)

在这种情况下,Al的运动有两个不同的部分:实际的运动和子弹的运动。请注意,我假设子弹发射并立即击中目标。由于我们希望最小化所花费的时间,因此直线路径是最佳解决方案。即Al的移动(从AD)以及' bullet'的轨迹。子弹是直线。

我们仍然可以使用教程中的相同三角形。唯一的区别是我们现在有一个新的AC公式来计算枪的范围(用圆圈表示)。

使用余弦规则:

乘以重新排列:

如果,解决方案是:

否则二次方程的解是:

与你的例子一样:

C点的计算方法与以前相同: