过年嘛 放松个五六天啥的 玩了个猎杀潜航的游戏
觉得那玩意挺有意思的
开年了 要美赛 写个设置鱼雷发射角的小程序玩玩
游戏嘛,反正大概简易版就是这个框架,自己补充呗 各种设定啥的,没怎么关心,就是总结一下里面的平面几何..水个文章玩玩
顺便练习一下pptx绘图
美赛的时候估计还是 matplotlib + origin + pptx ......
乐 大年初四滚去学习了... 可惜了 我想吃点必胜客再学习 ...... kfc也行啊
简陋的数学
以潜艇为原点 以潜艇潜艇方向为x轴正方向 建立平面直角坐标系
为什么设置的这么简单?
因为 猎杀潜航 是个二战游戏
那个点的潜艇似乎没有什么水面200米下打出鱼雷的技巧
似乎也没有能智能导航的鱼雷
补充一点,游戏里面的鱼雷应该是先顺着发射方向飞一段距离
然后转向(有且只能转向这一次)
什么 你想看博主证明这个角 那个角的旋转不变性....
博主读的是物理啊...不喜欢证明这个玩意
不要勾起一些难过的回忆
航线的问题
首先不要因为自己的水平低而低估数学家的能力
航线一般而言是确定的(省时省力)
敌人最佳的攻击处与攻击时间是确定的(根据你对敌人的了解推测)
护航舰队一定能针对你的弱点进行准确而高效的反鱼雷准备(你潜艇的建造技术不太可能泄漏,但是性能指标嘛,几乎是透明的,人家被你干掉那么多船,不能统计一下?)
计算AOB角
游戏中,我们用声纳的两次反馈信息确定敌船的速度
就是差分的思想...
计算发射角
我们用t来表示鱼雷从发射到命中的时间,实际运用中这个时间的设置涉及到:
撤退问题(打了就得跑啊,别人的被动声纳干啥吃的)
换目标时间(打完了你得接着干人家的船啊)
......
总之就是个多目标优化问题 ......
我们注意到,在二战的技术背景下,
敌舰(merchant 商船)一般而言是不太可能做机动航行的,同时为了保证到达时间符合预期,所以它的航行看成无加速运动似乎问题不大
事实上,这样的估计不可能准确
鱼雷在转向前的运行速度必然是难以估测的
一个正常的舰长不会在艇内把鱼雷先点了,调整好速度再打出去
如果鱼雷是被爆炸药推出去的,那么这必然是个减速过程
鱼雷转向时太靠近潜艇,可能会破坏潜艇本身(太小)
鱼雷在完成转向后的运行速度必然是难以估测的
燃料烧完了,质量减轻了,加速度变大了
水文条件难以估测
水文条件
我们必然是从一个超大的矩形域或圆形域来考虑这个问题的,
我们不妨设水文条件对鱼雷水平运行的加速度干扰如下(水面不可能这样的啊 只是演示 只是演示)
注:我们这里不考虑水雷是如何从海底80米腾飞到水面上的过程,那个技术德国二战应该还没有实现
鱼雷有限的自稳定系统
虽然什么自动导航,光纤引导什么的技术是不太可能在二战时期大规模应用的
但是我加一个水平偏移角探测器配合上舵机微调一下问题不大吧
同样的我们设鱼雷的自稳定系统可以提供加速度如下:
鱼雷有限的自导航系统
我们不追求鱼雷八百里开外一发入魂.但是八十米的时候是不是可以安排一个磁力导航系统呢?
要不然军舰的磁不白消了......
这样的话,又可以提供一个加速度
鱼雷动力系统稳定性分析
我们看到这一团恶心的,难以估测的一大坨,总是充满了厌恶之情...
所以我们经过复杂的分析之后,得出结论
贴脸输出吧,这不香吗?
博主觉得这种问题知识付费一下不为过吧...
注意
如果你初高中的时候没有因为 puppy love 或者别的什么而荒废的话,而且又能看到这个地方而且又玩 游戏玩得很溜的话,你就会发现,尾部鱼雷是怎么打的....这个模型似乎只适用于潜艇的某一个攻击位置啊!
是的,没错,不过...
我怎么知道,那又是另一个故事了...
对此..一个基于Python的小游戏
比较low...主要是练练手,C++面向对象写多了怕把Python 面向对象忘光了
import numpy as np
import random as r
import matplotlib.pyplot as plt
class ship():
#status1 二维位置 二维速度 二维加速度
#status2 舰艇长度 舰艇宽度
def __init__(self,status1,status2):
self.status1 = status1
self.status2 = status2
class submarine():
global SHIPS
global SUBMARINES
global TORPEDOES
#status1 二维位置 二维速度 二维加速度
#status2 舰艇长度 舰艇宽度
#status3 L1 theta2 该参数组为传入鱼雷参数组
def __init__(self,status1,status2):
self.status1 = status1
self.status2 = status2
def fire_torpedo(self,status3):
createvar = locals()
V1 = 80
L1 = 100
num = "t_"+str(round(random.random()*100000))
createvar[num] = torpedo(status3)
status1 = np.zeros(4)
status1[0],status1[1] = self.status1[0],self.status1[1]
#计算速度
v1,v2 = self.status1[2],self.status1[3]
Vx = V1 * (v1)/(v1**2+v2**2)**0.5
Vy = V1 * (v2)/(v1**2+v2**2)**0.5
status1[2],status1[3] = Vx,Vy
num.status1 = status1
TORPEDOES.append(num)
def sonar(self):
sonar_range = 10000
x,y = self.status1[0],self.status1[1]
SIGNAL = []
for i in SHIPS:
d = (x-i.status1[0])**2+(y-i.status1[1])**2
if sonar_range**2 >= d:
#模块化计算a
part1 = np.arctan(self.status1[1]/self.status1[0])
part2 = np.arctan((i.status1[1]-y)/(i.status1[0]-x))
a = np.pi - part1 - part2
SIGNAL.append(np.array([d,a]))
print(SIGNAL)
return SIGNAL
class torpedo():
#status1 二维位置 二维速度
#status2 长度 宽度
#status3 L1 theta2 该参数组为传入鱼雷参数组
def __init__(self,status1,status3):
self.status1 = status1
self.status3 = status3
def run():
global SHIPS
global SUBMARINES
global TORPEDOES
global dt
for ship in SHIPS:
#更新位置
ship.status1[0] += dt * ship.status1[2]
ship.status1[1] += dt * ship.status1[3]
ship.status1[0] += dt**2 * ship.status1[4]
ship.status1[1] += dt**2 * ship.status1[5]
#更新速度
ship.status1[2] += dt * ship.status1[4]
ship.status1[3] += dt * ship.status1[5]
for ship in SUBMARINES:
#更新位置
ship.status1[0] += dt * ship.status1[2]
ship.status1[1] += dt * ship.status1[3]
ship.status1[0] += dt**2 * ship.status1[4]
ship.status1[1] += dt**2 * ship.status1[5]
#更新速度
ship.status1[2] += dt * ship.status1[4]
ship.status1[3] += dt * ship.status1[5]
for ship in TORPEDOES:
#更新位置
ship.status1[0] += dt * ship.status1[2]
ship.status1[1] += dt * ship.status1[3]
ship.status1[0] += dt**2 * ship.status1[4]
ship.status1[1] += dt**2 * ship.status1[5]
def bomb():
global SHIPS
global SUBMARINES
global TORPEDOES
for tor in TORPEDOES:
for ship in SHIPS:
xt,yt = tor.status1[0],tor.status1[1]
xs,ys = ship.status1[0],ship.status1[1]
tol = 1
if (xt-xs)**2 + (yt-ys)**2 <= 1:
print("BOMB!")
SHIPS.remove(ship)
TORPEDOES.remove(tor)
def calculate_theta1(signal1,signal2):
d1,a1 = signal1
d2,a2 = signal2
d3 = d1**2+d2**2-2*d1*d2*np.cos(a1-a2)
#theta1 模块化计算
part1 = d1**2+d3**2-d2**2
part2 = 2*d1*d3
print(np.arccos(part1/part2))
return np.arccos(part1/part2)
def calculate_theta2(Datapack):
#L1 = 100
#L2,V1,V2,V3,t,theta1
L1,L2,V1,V2,V3,t,theta1 = Datapack
#theta2 模块化计算
part1 = (L1**2-L2**2)+V3**2*t**2
part2 = -V2**2*(t-L1/V1)**2
part3 = -2*L1*V3*t*np.cos(theta1)
part4 = 2*L2*V2*(t-L1/V1)
part5 = (part1+part2+part3)/part4
theta2 = np.arccos(part5)
return np.array([L1,theta2])
def Plot(Time):
global SHIPS
global SUBMARINES
global TORPEDOES
fig = plt.figure(figsize=(12,6))
ax1 = plt.subplot(121)
for i in SUBMARINES:
ax1.scatter(i.status1[0],i.status1[1],s=4,c="blue")
for i in TORPEDOES:
ax1.scatter(i.status1[0],i.status1[1],s=2,c="yellow")
plt.grid()
ax2 = plt.subplot(122)
for i in SUBMARINES:
ax2.scatter(i.status1[0],i.status1[1],s=4,c="blue")
for i in TORPEDOES:
ax2.scatter(i.status1[0],i.status1[1],s=2,c="yellow")
for i in SHIPS:
ax2.scatter(i.status1[0],i.status1[1],s=8,c="red")
plt.grid()
plt.savefig(str(round(Time,2))+".jpg")
#plt.pause(0.02)
plt.cla()
if __name__ == "__main__":
ship1 = ship(np.array([300,700,2,2,0,0]),np.array([130,35]))
SHIPS = [ship1]
submarine1 = submarine(np.array([500,200,4,2,0,0]),np.array([38,7]))
SUBMARINES = [submarine1]
TORPEDOES = []
Time = 0
dt = 5
while Time<1000:
run()
bomb()
Plot(Time)
Time += dt
while input("go or not")=="go":
#try:
eval(input())
#except:
# print("wrong")
# continue