鱼雷的发射角设置

过年嘛 放松个五六天啥的 玩了个猎杀潜航的游戏

觉得那玩意挺有意思的

开年了 要美赛 写个设置鱼雷发射角的小程序玩玩

游戏嘛,反正大概简易版就是这个框架,自己补充呗 各种设定啥的,没怎么关心,就是总结一下里面的平面几何..水个文章玩玩

顺便练习一下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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

River Chandler

谢谢,我会更努力学习工作的!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值