先看我上传的视频,看看是否是你们想要的效果:

【算法课设】 卫星系统 运行情况存档_哔哩哔哩_bilibili

【算法课设】存档2_哔哩哔哩_bilibili

注意:视频中没有画出地球那种越靠极点纬度线越短的情况,但面积计算是没有问题的,因为画图和计算分离,图只是可视化,但面积等数据用的是微积分。

1、问题背景

  当前,卫星移动通信、气象预报、遥感探测、军事侦察、资源勘探、灾害监
测、导航定位等多个领域发挥着越来越重要的作用。而且,在一般的航天任务应
用中,我们往往需要使用一群卫星共同来完成任务。将一群卫星的集合,称作卫
星星座。
  在每个时刻,卫星的服务范围可以近似成一个圆锥形的区域。该锥形区域在
地面上的投影为球面圆形的(注:球面圆,不是平面圆)。如果该时刻,地面目标
在该圆形区域内,则卫星可以对该地面目标提供服务,称作“地面目标在该时刻
被卫星覆盖”。

2、第一个问题----计算卫星与目标的时间窗口

  卫星对一个地面目标的时间窗口,是指在仿真时间内,卫星对目标可以提供
服务的时间段的集合。时间窗口可以表示为一个时间区间,在该区间内卫星能够
对目标提供服务,而不在该时间区间内,卫星不能对目标提供服务。
卫星星座对一个地面目标的时间窗口,为星座中每颗卫星对目标时间窗口的
并集。
完成如下计算:
(1) 对以下每个目标,计算星座对其时间窗口。同时,统计时间窗口的最
大值、最小值与累积值。对每个目标,计算其时间间隙,并统计时间间隙的最大
值与累积值。
目标的数据如下:
(2) 在经度 75°E-135°E,纬度范围 0°N-55°N 的区域范围内,计算每
个坐标的时间间隙的最大值、时间间隙的和,以及时间间隙平方和三个指标,并将结果分别以可视化形式展示出来,经纬度的离散化精度可调节,最小需要考虑
到 0.1°。
2.1、问题一分析
据我所知,每年的数据是不一样的,如果有人在做此课设,写代码时需要注意自己写的城市个数与每个城市的名称地点位置。
2.1.1、数据预处理
老师给我们的数据包含了9个卫星在一天之内每一秒的位置信息,这些点也就组成了该卫星服务的“圆”(看作是平面圆,之后说到的矩形也是如此,但计算面积是要用微积分)区域。
那么我们可以想到,有城市位置,有9个圆的位置,那是不是把这个城市与某秒9个圆的位置进行计算,看看是否在圆内,如果9个圆都不覆盖此城市,那说明该秒时这个城市不被服务。
但这里遇到一个问题:每一秒每个卫星都有21个点(没记错的话),那数据量是不是有点太大了。所以我们拿到题目不要上来就刷刷写代码,没什么luan用,先分析问题。
那么我们可以想到,能不能找两个点,这两个点正好是该秒时21个点的最高点与最低点,这样就可以得到圆直径,然后两个点的中点就是圆心。
但我发现以前的学长用的就是这个方法,你们应该可以找得到。那么我们要有所创新,不要和别人一样,而且,只要两个点其实误差会稍大(虽然估计大不了千分之一)。那么我将给出新的方法
*数据预处理---取圆上3个点通过克莱姆法则求解半径与圆心 
我们在选取最高点和最低点的情况下,再选取一点,你们看那个学长的文章应该能知道最高和最低点,然后我们在要最左边点或最右边点,自己去看一下是第几个点。然后看下图

(本图取自本人的汇报ppt,希望对你们有帮助)

接下里将放出数据预处理代码,这些代码是使用c++写的,请自己用c++开一个空项目,将下列代码放入cpp中,把老师给的卫星数据放入项目文件,运行就能得到结果。目的是将卫星信息简化,将每个卫星每一秒的中心位置或者说圆心位置写入文件中。那么文件应该包含86400个经度纬度信息。

#include<iostream>
#include<cmath>
#include<fstream>
#include <stdio.h>
#include<stdlib.h>
#include<string>
#include<vector>
#include <typeinfo>//typeid
using namespace std;double Radius[86400];//用于临时保存每一秒对应的半径
double test1[10];
double aveRadius[9];double pingJun(double* radius)
{double cul = 0;for (int i = 0; i < 86400; i++){cul += radius[i];}//freturn (cul / (double)86400);
}double HangLieShi(double a11, double a12, double a21, double a22)
{return (a11 * a22 - a12 * a21);
}
class myPoint
{
public:myPoint(){x = 0, y = 0;}myPoint(double x0, double y0) { x = x0; y = y0; }myPoint(myPoint& P) { x = P.x; y = P.y; }myPoint& operator=(const myPoint& P){x = P.x;y = P.y;return *this;}~myPoint() {}void set(double x0, double y0){x = x0;y = y0;}double x, y;
};
myPoint Position[9][86400];//第i个卫星的第j秒的圆心
class Line
{
public:Line(myPoint a0, myPoint b0) :a(a0), b(b0){if (a.x == b.x) { A = 0; B = 1; C = (a.y + b.y) / 2; }else if (a.y == b.y) { A = 1; B = 0; C = (a.x + b.x) / 2; }else{A = 1;B = (a.x - b.x) / (a.y - b.y);C = (a.x + b.x) / 2 + B * (a.y + b.y) / 2;}}~Line() {}myPoint a, b;double A, B, C;
};class Circle
{
public:Circle(){}Circle(myPoint a0, myPoint b0, myPoint c0) :a1(a0), b1(b0), c1(c0) {}~Circle() {}double calculation(int number, int time);//计算圆心,半径void reSet(myPoint&a0, myPoint&b0, myPoint&c0){a1 = a0; b1 = b0; c1 = c0;}
protected:myPoint a1, b1, c1;double x0, y0, R;
};
//number对应卫星编号,time即时刻,要将每个卫星每时刻对应的圆心坐标进行保存
double Circle::calculation(int number, int time)
{Line l1(a1, b1), l2(a1, c1);double J;J = HangLieShi(l1.A, l2.A, l1.B, l2.B);//简单来说呢,就是克莱姆法则求解方程//如果两个直线不同,说明可以使用克莱姆法则求解if (J){//将向量的常量代替矩阵对应的值,求出圆心x0 = HangLieShi(l1.C, l2.C, l1.B, l2.B) / J;y0 = HangLieShi(l1.A, l2.A, l1.C, l2.C) / J;Position[number][time].set(x0, y0);//使用圆方程解半径R = sqrt((a1.x - x0) * (a1.x - x0) + (a1.y - y0) * (a1.y - y0));}else{return -1;}return R;
}//读文件函数
void Read(int number, double &radius)
{ifstream  ifs;//流对象//读文件0-8if (0 <= number && 9 > number){switch (number){case 0:{ifs.open("SatCoverInfo_0.txt");break;}case 1:{ifs.open("SatCoverInfo_1.txt");break;}case 2:{ifs.open("SatCoverInfo_2.txt");break;}case 3:{ifs.open("SatCoverInfo_3.txt");break;}case 4:{ifs.open("SatCoverInfo_4.txt");break;}case 5:{ifs.open("SatCoverInfo_5.txt");break;}case 6:{ifs.open("SatCoverInfo_6.txt");break;}case 7:{ifs.open("SatCoverInfo_7.txt");break;}case 8:{ifs.open("SatCoverInfo_8.txt");break;}default:{return;}}}else{return;}//ifs.open("SatCoverInfo_0.txt");if (!ifs){cout << "读取失败" << endl;return ;}//打开指定文件int getLineNum = 22;//每次读取22行double x = 0, y = 0;char name[20];myPoint a, b, c;Circle A;//读文件。for (int j = 0; j < 86400; j++){for (int i = 0; i < getLineNum; i++){if (i == 0){ifs.getline(name, 20);continue;}ifs >> x >> y;if (i == 1){a.set(x, y);}else if (i == 6){b.set(x, y);}else if (i == 11){c.set(x, y);}else if (i == 21){ifs.getline(name, 20);}}A.reSet(a, b, c);Radius[j] = A.calculation(number, j);}ifs.close();radius = pingJun(Radius);
}void Write(int number)
{ofstream  ofs;//流对象//读文件0-8if (0 <= number && 9 > number){switch (number){case 0:{ofs.open("Position_0.txt");break;}case 1:{ofs.open("Position_1.txt");break;}case 2:{ofs.open("Position_2.txt");break;}case 3:{ofs.open("Position_3.txt");break;}case 4:{ofs.open("Position_4.txt");break;}case 5:{ofs.open("Position_5.txt");break;}case 6:{ofs.open("Position_6.txt");break;}case 7:{ofs.open("Position_7.txt");break;}case 8:{ofs.open("Position_8.txt");break;}default:{return;}}}else{return;}//是否打开成功if (!ofs){cout << "读取失败" << endl;return;}for (int j = 0; j < 86400; j++){ofs << Position[number][j].x << "         " << Position[number][j].y<<endl;}
}int main()
{for (int i = 0; i < 9; i++){Read(i, aveRadius[i]);Write(i);}for (int i = 0; i < 9; i++){cout << "第" << i<< "个卫星区域平均半径为:" << aveRadius[i] << endl;}//一下的注释代码是最开始使用来求平均半径的//Read(3, aveRadius[3]);//Write(3);//cout << "平均半径为:" << aveRadius[3] << endl;return 0;
}

那么以上,我们就可以把第0到第8个卫星的位置信息写入文件中,第0个卫星的文件是Position_0,第1是Position_1,后面同理。

然后这里我直接给出9个卫星的平均半径,之后在qt中直接用这个半径作为每个卫星的半径就可以了。卫星服务区的半径是:7.0068

2.2、求城市时间窗口与时间间隙

时间窗口,比如0 - 86399秒内,第1秒-第400秒该城市被卫星服务(只要被9个卫星的其中一个服务就是被服务),那么产生一个时间窗口[1,400],那么第0秒和第401秒是不被服务的。

我下面再讲的仔细些,包含代码,先写城市City类,成员变量有:城市名称、经度、纬度、时间窗口的QVector。然后写一个时间窗口TimeSlot类,成员变量:startTime、overTime、length。

[startTime,overTime],length = overTime - startTime + 1。

然后卫星的类Satellite,成员变量:double *x,double *y。

qt的代码如下:

city.h

#ifndef CITY_H
#define CITY_H#include"timeslot.h"
#include<QVector>
//这是一个城市的类
class City
{public:double longitude;//城市的经度double latitude;//城市的纬度QString name;//城市的名字QVector<TimeSlot> slot;//该城市的时间窗口,后面会计算,出现一个窗口时候就会push进去一个窗口public:City();};//保存城市的表
class CityList
{
public:City city[19];//一共有19个城市//构造函数CityList();int location(QString n);//传入名字,定位};#endif // CITY_H

city.cpp

#include "city.h"City::City()
{this->longitude = 0;this->latitude = 0;name = "";
}CityList::CityList()
{city[0].name = "奥克兰";city[0].longitude = 237.87;//-122.13city[0].latitude = 37.47;//city[1].name = "敖德萨";city[1].longitude = 30.46;city[1].latitude = 46.3;//city[2].name = "冈山";city[2].longitude = 133.54;city[2].latitude = 34.4;//city[3].name = "俄克拉荷马城";city[3].longitude = 262.68;//-97.32city[3].latitude = 35.29;//city[4].name = "鄂木斯克";city[4].longitude = 55;city[4].latitude = 73.22;//city[5].name = "奥拉涅斯塔克";city[5].longitude = 290.42;//69.58city[5].latitude = 12.3;//city[6].name = "奥拉多";city[6].longitude = 278.78;//-81.22city[6].latitude = 28.3;//city[7].name = "大阪";city[7].longitude = 135.3;city[7].latitude = 34.4;//city[8].name = "奥斯陆";city[8].longitude = 10.41;city[5].latitude = 159.56;//city[9].name = "渥太华";city[9].longitude = 284.57;//-75.43city[9].latitude = 45.25;//city[10].name = "瓦拉杜古";city[10].longitude = 358.6;//-1.4city[10].latitude = 12.2;//city[11].name = "帕果帕果";city[11].longitude = 189.58;//-170.42city[11].latitude = -14.16;//city[12].name = "巨港";city[12].longitude = 104.5;city[12].latitude = -2.59;//city[13].name = "波赫恩";city[13].longitude = 158.1;city[13].latitude = 6.55;//city[14].name = "帕尔马";city[14].longitude = 2.39;city[14].latitude = 39.26;//city[15].name = "巴拿马";city[15].longitude = 280.7;//-79.3city[15].latitude = 8.57;//city[16].name = "帕皮提";city[16].longitude = 210.66;//city[16].latitude = -17.32;//city[17].name = "帕拉马里博";city[17].longitude = 304.86;//55.14city[17].latitude = 5.52;//city[18].name = "巴黎";city[18].longitude = 2.2;city[18].latitude = 48.51;
}int CityList::location(QString n)
{for(int i = 0; i < 19; i++){if(city[i].name == n){return i;}}return -1;
}

timeslot.h

#ifndef TIMESLOT_H
#define TIMESLOT_H//如题,这是一个时间段的类,用于保存各城市各时间窗口的值(开始时间、结束时间、时间长度)
class TimeSlot
{
public:int startTime;int overTime;int length;
public:TimeSlot();TimeSlot(int s, int o);void set(int start, int over);
};//时间间隙
class TimeGap
{};#endif // TIMESLOT_H

timeslot.cpp

#include "timeslot.h"TimeSlot::TimeSlot()
{startTime = 0;overTime = 0;length = 0;
}
TimeSlot::TimeSlot(int s, int o)
{startTime = s;overTime = o;length = overTime - startTime + 1;
}void TimeSlot::set(int start, int over)
{startTime = start;overTime = over;//[1, 5]的长度是 5 - 1 + 1//对于区间[l, r],长度为 r - l + 1length = overTime - startTime + 1;}

satellite.h

#ifndef SATELLITE_H
#define SATELLITE_H//卫星的类,保存半径与中心坐标,但由分析情况来看,半径已经不需要了
class Satellite
{
public:double *x;double *y;
public:Satellite();~Satellite();};#endif // SATELLITE_H

satellite.cpp

#include "satellite.h"Satellite::Satellite()
{x = new double[86400];y = new double[86400];
}Satellite::~Satellite()
{delete []x;delete []y;
}

2.2.1、时间窗口求解方法

mianwindow.cpp中的,主要看方法,代码的注释非常超级终极无敌tm详细,我认为我说的再多用处也不大,不如你们好好看看这个代码。

解释:设置bool类型的变量flag,一开始设置为false 若某一刻城市被服务,将flag置为true。 若某一刻不被服务,同时flag为true,说明产生了一个时间窗口 通过timeSlot的构造函数创建对象,将其 push_back到该城市的vector<timeSlor>容器中。同时flag置为false。

然后我此处只求了时间窗口,还有时间间隙呢,那么时间间隙我不太懂意思,有两种解释。

一:城市不被服务的时间段就是时间间隙。

二、两个时间窗口之间产生一个时间间隙。

请自己体会,我在课设中用的是第二种解释,你们可以去问老师到底是哪种。

只要弄明白下列代码,基本没什么问题了,时间间隙大不了你们自己写一个timeGap,或者通过方法用窗口求间隙,很简单的。当时我就是懒得再写一个timeGap了,现在想想,确实写一个会比较好。

时间窗口最大最小值、累计值就不要多说了吧?你好好想想TimeSlot里我为什么要写length,tnn的遍历一遍这个城市的QVctor<TimeSlot>容器不就有最大最小和累计了吗!!!!

间隙同理哈。

//读取卫星信息
void MainWindow::ReadFile(int number)
{ifstream ifs;switch (number){case 0:{ifs.open("D:/vc/z/myEarth/Position_0.txt");break;}case 1:{ifs.open("D:/vc/z/myEarth/Position_1.txt");break;}case 2:{ifs.open("D:/vc/z/myEarth/Position_2.txt");break;}case 3:{ifs.open("D:/vc/z/myEarth/Position_3.txt");break;}case 4:{ifs.open("D:/vc/z/myEarth/Position_4.txt");break;}case 5:{ifs.open("D:/vc/z/myEarth/Position_5.txt");break;}case 6:{ifs.open("D:/vc/z/myEarth/Position_6.txt");break;}case 7:{ifs.open("D:/vc/z/myEarth/Position_7.txt");break;}case 8:{ifs.open("D:/vc/z/myEarth/Position_8.txt");break;}default:{return;}}//将每一秒的信息读入for(int i = 0; i < 86400; i++){ifs>>satellite[number].x[i]>>satellite[number].y[i];//读入第number个卫星的第i时刻的位置信息}ifs.close();
}
//求平方
double culSquare(double a)
{return a*a;
}//请在mainwindow的构造函数中执行sInit(),初始化,这样我们一运行就把所有城市的时间窗口求完了
void MainWindow::sInit()
{//其实半径甚至就是一样/*satellite[0].radius = 7.00681;satellite[1].radius = 7.00679;satellite[2].radius = 7.00681;satellite[3].radius = 7.0068;satellite[4].radius = 7.0068;satellite[5].radius = 7.00682;satellite[6].radius = 7.00679;satellite[7].radius = 7.0068;satellite[8].radius = 7.00682;*///一个循环  每个卫星每秒钟对应的x ,y读进来for(int i = 0; i < 9; i++){ReadFile(i);}int start = 0;//将各城市的时间窗口计算出来,外循环遍历城市for(int i = 0; i < 19; i++){bool flag = false;//记录城市是否被卫星星座覆盖//中间循环遍历时间for(int j = 0; j < 86400; j++){//内层循环遍历卫星,时间复杂度较高。int number =0;//当前时间段未提供服务的卫星个数for(int k = 0; k < 9; k++){//判断城市是否在该卫星的搜索范围内,看方程(x-x0)*(x-x0) + (y-y0)*(y-y0)是否小于等于radius//第i个城市的x-该卫星的x,即经度longitude,y即纬度latitude//第k个卫星在第j秒的数值if((culSquare(theCityList.city[i].longitude - satellite[k].x[j]) + culSquare(theCityList.city[i].latitude - satellite[k].y[j])) <= culSquare(radius)){//如果该时间段处在星座范围内,且flag标记false,说明此时刻开始进入星座的范围if(!flag){start = j;//j就是当前时间flag = true;//标记被覆盖}break;//退出当前卫星循环,因为只要有一个卫星提供就算星座在提供}//执行到这一步,说明此卫星没有提供服务,Number++number++;//若9个if(flag && number == 9){//此时不再星座内,但是flag却为true,说明有了一个时间窗口出现//传入start,和结束时间j - 1TimeSlot t(start, j - 1);//把tpush给该城市的时间窗口VEctortheCityList.city[i].slot.push_back(t);//然后把flag置为falseflag = false;}}}}/*ifstream ifs1;ifs1.open("D:/vc/z/myEarth/us.txt");for(int i = 0; i < 3369; i++){ifs1>>point[i].longitude>>point[i].latitude;}ifs1.close();*/
}

3、最后

最后一篇文章我会把全部资源发到百度云,里面包含克莱姆法则的预处理、最重要的qt源程序本体、还有美国多边形的分割。如果你们现在弄的不是美国,也不要紧张,我会把这种类似问题的方法讲解的一清二楚。不过我看学长弄的是求区域时间间隙最小最大点啥的,用了粒子群优化算法那个,我怀疑你们应该搞的是别的。不过我还是会把这种某国、某区域多边形的分割方法放出来,万一你们今年搞的是什么英国、澳大利亚啥的呢hh。

卫星系统算法课程设计 - 第一部分:城市时间窗口、间隙等相关推荐

  1. 数据结构与算法课程设计——C语言《职员薪资查询系统》

    数据结构与算法课程设计--C语言<职员薪资查询系统> 温馨提示:课设要自己去操作,自己写代码,可以借鉴他人代码,学习思路和一些操作,切不可完全抄袭!!! 总体说明:设计一个职员薪资查询系统 ...

  2. 数据结构c语言程序设计报告,数据结构与算法课程设计报告模版.doc

    数据结构与算法课程设计报告模版.doc 数据结构与算法课程设计报告题 目本科生导师制问题与家族关系查询系统院 (系) 信息科学与工程 专业班级 计算机应用技术1301班 学生姓名 顾 泉 学 号 20 ...

  3. 卫星系统算法课设(一)-志明老师

    问题 1 选题介绍 当前,卫星移动通信.气象预报.遥感探测.军事侦察.资源勘探.灾害监测.导航定位等多个领域发挥着越来越重要的作用.而且,在一般的航天任务应用中,我们往往需要使用一群卫星共同来完成任务 ...

  4. 数据结构与算法课程设计大作业

    考   核   要  求 课程编号:400802010    课程名称:数据结构与算法课程设计考试形式:大作业 大作业1-9见我的下载 里面包含多个版本的设计 文件有cpp文件设计文档总结等 一.设计 ...

  5. java万年历设计报告_JAVA《万年历系统》课程设计报告附源码.doc

    JAVA<万年历系统>课程设计报告附源码 学号<> 课程设计报告 万年历系统专业:计算机科学与技术班级:姓名:学号:指导教师:成绩: 计算机与信息工程系 2014年6月6日目录 ...

  6. java万年历课程设计代码,JAVA《万年历系统》课程设计

    JAVA<万年历系统>课程设计 面向对象程序设计面向对象程序设计 课程设计报告课程设计报告 题目题目 万年历系统万年历系统 专业专业 计算机科学与技术计算机科学与技术 班级班级 姓名姓名 ...

  7. 万年历java课程设计报告_java《万年历系统》课程设计报告附源码.doc

    java<万年历系统>课程设计报告附源码.doc 学号<面向对象程序设计>课程设计报告题目:万年历系统专业:计算机科学与技术班级:姓名:学号:指导教师:成绩:计算机与信息工程系 ...

  8. matlab仿真转速波形为负,转速、电流双闭环直流调速系统的课程设计MATLAB仿真.docx...

    转速.电流双闭环直流调速系统的课程设计MATLAB仿真 PAGE \* MERGEFORMAT25 任务书1.设计题目转速.电流双闭环直流调速系统的设计2.设计任务某晶闸管供电的双闭环直流调速系统,整 ...

  9. 数据结构计算机专业教学计划编制,数据结构与算法课程设计报告--教学计划编制...

    数据结构与算法课程设计报告--教学计划编制 数据结构与算法课程设计报告题目教学计划编制目录一.需求分析311系统概述3111研究背景3112研究意义及目的312具体分析4121功能需求分析4122运行 ...

  10. 数据结构与算法课程设计之五子棋(人机)

    数据结构与算法课程设计之五子棋(人机) 五子棋是全国智力运动会竞技项目之一,是一种两人对弈的纯策略型棋类游戏.通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成五子连线者获胜. 这是 ...

最新文章

  1. gdi按钮重绘背景黑色_PS快速抠图换背景教程 PS怎么抠图放在另一张图 这个方法简单万能...
  2. linux中流设备_Linux设备驱动子系统终极弹
  3. 化工设备与反应器 第二章 直杆的拉伸与压缩
  4. excel转html放在tomcat,Excel转web!把excel在线打开??
  5. CentOS 下线,TencentOS Server 全新登陆带来最强支持
  6. UVa 11324 最大团(强连通分量缩点)
  7. java super关键字简述
  8. 微信支付 SDK 惊爆漏洞:黑客可 0 元购买任意商品
  9. centos7安装kubernetes 1.1
  10. Genome2D官方博客及教程
  11. C++基础——C++风格的类型转换(static_cast、const_cast、dynamic_cast、reinterpret_cast)
  12. mysql80110_M1938工作室出品N801苹果CMSV10高级自适应模板
  13. Axure rp8.1.0.3381激活码(2019-07-26 亲测可用)
  14. 数据可视化分析工具大集合
  15. JS GZIP压缩,GZIP解压
  16. 投资 - 指标介绍: MACD
  17. PowerBI获取报表使用指标
  18. PhotonServer中PhotonServer.config文件的配置
  19. C# 模拟鼠标移动和点击(转载)
  20. 公司发布新闻宣传稿件是选新闻媒体网站还是自媒体?

热门文章

  1. 在qt中出现During startup program exited with code 0xc0000135错误原因
  2. 流量魔盒FlowBox 发行的代币是DMC骗局分析
  3. android开发板单片机蓝牙通信
  4. Spring MVC异常统一处理的三种方式
  5. Eclipse官方下载最新版
  6. 微信html5线上卡券,16.7.1HTML5网页领取卡券
  7. OVS使用VLAN隔离VM流量
  8. Android 删除文件app,手机删除文件怎么恢复?手机恢复删除App
  9. kvm连接服务器显示不全有重影,KVM多电脑切换器常见故障排查及处理方法
  10. 内集理论是处理非标准分析的新方法