Geometry 带半径的二维弹丸弹道计算

Geometry 带半径的二维弹丸弹道计算,geometry,2d,game-physics,trigonometry,Geometry,2d,Game Physics,Trigonometry,我有一个2D游戏,角色(Al)试图从NPC(Bu)中“保存”另一个角色(Ho) Al和Bu具有恒定速度(萨利静止不动) 我需要弄清楚如何计算Al应该瞄准什么点才能停止Bu 我能够在阅读后编写这个程序。我将一些pylab代码转换为numpy def interception(Al, Bu, Ho, Sa, Sb): """ Returns ``(t_C, C)`` if A can catch B, before B reaches H. Otherwise, returns `

我有一个2D游戏,角色(
Al
)试图从NPC(
Bu
)中“保存”另一个角色(
Ho

Al
Bu
具有恒定速度(萨利静止不动)

我需要弄清楚如何计算
Al
应该瞄准什么点才能停止
Bu

我能够在阅读后编写这个程序。我将一些
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
这很好,但这里有一个问题,我想弄清楚。我想调整此
拦截
函数,使其具有另一个参数
Al_半径
。你看,
Al
有枪,当
Bu
Al\u半径范围内时,
Al
可以射击
Bu


我很确定,根据
Al
的射程,他的目标位置可能会改变(例如,侧翼可能比直接走向
Bu
Ho
之间的路径更快)。

在这种情况下,
Al
的运动有两个不同的部分:实际运动和“子弹”的运动。请注意,我假设子弹会立即开火并击中目标。由于我们希望尽量减少所需时间,直线路径是最佳解决方案。也就是说,
Al
的运动(从
A
D
)和“子弹”的轨迹呈直线

我们仍然可以使用教程中相同的三角形。唯一的区别是我们现在有了一个新的AC方程来解释枪的射程(用圆圈表示)

使用余弦规则:

倍增并重新排列:

如果是,解决方案是:

否则,二次方程的解为:

正如你的例子:

点C的计算方法与前面相同:
在这种情况下,
Al
的运动有两个不同的部分:实际运动和“子弹”的运动。请注意,我假设子弹会立即开火并击中目标。由于我们希望尽量减少所需时间,直线路径是最佳解决方案。也就是说,
Al
的运动(从
A
D
)和“子弹”的轨迹呈直线

我们仍然可以使用教程中相同的三角形。唯一的区别是我们现在有了一个新的AC方程来解释枪的射程(用圆圈表示)

使用余弦规则:

倍增并重新排列:

如果是,解决方案是:

否则,二次方程的解为:

正如你的例子:

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