基于python的目标跟踪(Python的自动追踪算法)
这涉及到拦截导弹的自动跟踪。最近看到一个有趣的自动跟踪算法,一个Python的简单模拟版,分享给大家。
在我们设计2D射击游戏时,经常会用到自动跟踪算法。这个听起来很高大上的东西,其实并不是军事专利。如果用数学方法求解,需要解微分方程。
它没有一些数学基础是很难算出来的。然而,当我们有一台电脑时,情况就不同了。依靠计算机极快的计算速度,利用微分的思想和一点三角学的知识就可以实现。
好了,事不宜迟,让看一下它的算法原理,看图:
后面会用到pygame来演示,他的坐标系是Y轴向下的,所以这里我们也用Y轴向下的坐标系。
算法的大致思路是根据上图将时间T分成足够小的段(例如1/1000,时间段越小越精确),每段构造成上图的三角形,从而计算出导弹下一个时间段的方向(即a)和距离(即vt=|AC|)。此时目标在第二时间段内移动,计算刚刚完成。
假设初始状态下导弹和目标的坐标分别为(x1,y1)和(x,y),构造一个直角三角形ABE。这个三角形用来求 a的正弦和余弦值,因为vt是我们自己设定的,所以我们需要计算A到C点的X和Y坐标移动了多少,移动的值就是AD和CD的长度,可以分别乘以cosa和sina乘以vt。
计算sina和cosa,正弦对比是斜的,余弦相邻对比是斜的,斜边可以用两点距离公式计算,即:
因此
AC的长度就是导弹的速度乘以时间|AC|=vt,然后就可以计算出AD和CD的长度。所以这个时间片过去后,导弹应该出现在新的位置C,它的坐标是旧点A的X加AD,Y减CD。
所以,C点的新坐标是:
就一直重复这个操作。好吧,为了更形象,把第一个时间片和第二个时间片放在一起看一下:
首先是时间片构建的三角形是ABE。一个时间片后,目标从B点到D点,此时导弹在C点,那么构造一个新的三角形CDF,重复刚才的计算过程。
图中的角度b是导弹需要旋转的角度。实际上,只需要在每个时间片上校正导弹的方向。如何让导弹改变方向,不是我们需要研究的问题。
好吧,既然Python 最近用s pygame库做小游戏玩,接下来我们就用pygame来演示这个效果。效果如下:
简单的代码如下:
importpygame,sysfrommathimport * py game . init()screen=py game . display . set _ mode((800,700),0,32)missile=py game . image . load(element/red _ pointer . png ).convert_alpha()x1,y1=100,初始发射位置60 #导弹速度=800#导弹速度时间=1/1000#每个时间片的长度Clock=py game . time . Clock()old _ angle=0 while true:forevent inpygame . event . Get():if event . type==py game . quit:sys . exit()Clock . tick(300)x,y=pygame.mouse.get _ pos () #获取鼠标位置,鼠标为要打击的目标。Distance=sqrt (power (x1-x,2) power (y1-1) 2) #两点距离公式section=velocity * time # distance Sina=(Y1-y)/distance cosa=(x-x1)/distance angle=atan2(y-Y1,x-x1) # radian value x1,y1=(x1 section*cosa,Y1-section * Sina)d _ angle=degrees(angle)# radian to angle screen . blit(miss,(x1-miss . get _ width),Y1-miss。get _ height()/2))dis _ angle=d _ angle-old _ angle # dis _ angle是需要换到下一个位置的角度。old_angle=d_angle#更新初始角度pygame.display.update()
如果只把导弹看成一个质点,那么上面的算法就足够了。我没有不要旋转导弹,因为一个粒子不会不管它的头和尾,都不需要旋转。当然,这预先假定它不会如果你加载的导弹图像很小,这看起来不是问题。
但是它在pygame中旋转不容易(或者可能我我很无知)。好吧,让先把图片换成长方形的,再加上旋转功能,看看效果如何。
missiled=pygame . transform . rotate(missile,-(d _ angle))screen . blit(missiled,(x1-missile.get_width()、y1-missile.get_height()/2))
因为图片的坐标点是其左上角的点,如果我们想让图片的坐标固定在箭头的尖点,那么就把图片的实际打印位置X减少图片的长度,y减少一半的宽度。
但实际操作效果并不好:
方向大致相同,但图中箭头的尖点没有不要总是跟着鼠标走。为什么?经过我的研究(它还没有因为这个问题还没有发表。尚未解决),
我发现是这张图旋转的机制。让让我们看看旋转后的图片是什么样的:
在旋转后的图像变为蓝色的范围内,图像的尺寸根据旋转角度而变得不同。让让我们看看90度的旋转:
我们发现旋转后的图像不仅放大了区域,还改变了导弹头部的位置。那么应该如何解决这个问题呢?其思路是,每次旋转图片后,找出旋转图片头部的位置(图中绿色箭头点),然后移动绿色图片的打印位置,使旋转后的导弹头部与我们实际参与计算的导弹头部位置对齐。运动之后,应该是这样的:
这样两个导弹头的点就重合了。接下来,我们分析寻找旋转的导弹头的算法。根据旋转角度的不同,不同象限的旋转角度的参数是不同的,所以我们可以分为这四种情况。
1、2象限:
象限3,4,它的旋转只有正负0-180,所以象限3,4为负角。
当图片显示时,我们移动它。
screen.blit(missiled,(x1-width (x1-C[0]),y1-height/2 (y1-C[1]))
这里的(x1-宽度,y1-高度/2)其实就是上图中的(x1,y1)。
所以最后我们加上相关的算法代码,效果很完美。
你我们结束了。最后附上所有算法代码:
importpygame,sysfrommathimport * py game . init()font 1=py game . font . sys font(微软microsoftyaheimicrosoftyaheiui ,23)textc=font 1 . render(*'True,(250,0,0))screen=py game . display . set _ mode((800,700),0,32)missile=py game . image . load(element/rect 1 . png ).convert _ alpha()height=Missile . Get _ height()width=Missile . Get _ width()pygame . mouse . set _ visible(0)x1,y1=100,初始发射位置60 #导弹速度=800#导弹速度时间=1/1000#每个时间片的长度Clock=pygame . time . Clock()A=()B=()C=()while true:foreventinpygame . event . Get():if event . type==pygame . quit:sys . exit()Clock . tick(300距离=sqrt (power (x1-x,2) power (y1-1) 2) #两点距离公式section=velocity * time # distance Sina=(Y1-Y)/distance cosa=(X-X1)/distance angle=atan2(Y-Y1,X-X1) #两点间线段的弧度值方了=度(角度)#弧度转角x1 y1=(x1 section*cosa,Y1-section * Sina)missiled=py game . transform . rotate(导弹,-(方了))if0=-方了=90:A=(角
最后
这是一个用Python实现的简单的自动跟踪算法。真正的导弹拦截跟踪算法要复杂得多。
审计彭静
推荐阅读
- fpga的开发流程分析与实施(FPGA的开发流程分析)
- 二十万房产继承诉讼费快速计算器 诉讼费快速计算器
- 十个汽车品牌的档次排序? 全球汽车品牌档次排名
- 美淘app软件介绍(美淘app)
- 欠条的格式及注意事项有哪些 借条模板格式样本
- 战地坦克完整版游戏介绍(战地坦克完整版)
- 五菱荣光_五菱荣光怎么样
- 发明专利号如何查询 专利查询网官网查询
- 如果飞机突然坠落怎么办?(如果飞机突然坠落应该怎么办)
- 诺基亚5320怎么下载安装软件和游戏? 诺基亚手机软件下载中心
- 国产猛禽是什么车_国产猛禽
- 免费律师法律援助电话是多少 免费律师法律援助电话
- 绿色儿童桌面软件介绍(绿色儿童桌面)
- 如何阻挡电磁波干扰的方法(如何阻挡电磁波干扰)
- 新买的雨刮还是刮不干净,雨刮到底应该怎么选择(新买的雨刮还是刮不干净,雨刮到底应该怎么选)
- 宁夏日报电子版软件介绍(宁夏日报电子版)
- 私人做亲子鉴定多少钱 2022年做亲子鉴定多少钱
- 如果你有8000亿能做什么工作(如果你有8000亿能做什么)
- 绿野户外网官方版软件介绍(绿野户外网官方版)