Geometry 带半径的二维弹丸弹道计算
我有一个2D游戏,角色(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 `
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的计算方法与前面相同: