机场跑道入侵检测(C++、Qt)

2023-10-08 17:48

本文主要是介绍机场跑道入侵检测(C++、Qt),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

机场跑道入侵检测

    • 实现原理:
    • 效果
    • 关键代码(只提供思路和部分代码,并非完整代码。)

实现原理:

1、读取并解析机场跑道、车道数据,显示和存储。
2、根据本机的经纬度坐标,确定本机所在跑道,并计算出一个多边形区域。
3、实时获取它机、车辆坐标数据,判断是否位于本机起飞跑道的多边形范围内。
4、如果它机、车辆坐标位于本机跑道,则预警。

通过面积法,判断点P是否在四边形(A,B,C,D)内。如果在四边形内,则四边形的面积=面积(P,A,B)+面积(P,B,C)+面积(P,C,D)+面积(P,D,A),反之不在四边形内。

如下图:
在这里插入图片描述

效果

视频地址:https://www.bilibili.com/video/BV1bK4y147R1/

关键代码(只提供思路和部分代码,并非完整代码。)

	//judge quadrangle is contain point pbool isInQuadrangle(QVector<QPointF> &pointfs, QPointF p);//calculate triangle areadouble getTriangleArea(QPointF p1, QPointF p2, QPointF p3);//get Vertex of Quadrangle void getQuadrangleVertex(QPointF m1, QPointF m2, float direction, double len, QVector<QPointF> &pointfs);//polygon vertexes can be sorted clockwisevoid clockwiseSort(QVector<QPointF> & vPoints);bool PointCmp(const QPointF &a, const QPointF &b, const QPointF &center);double getAngle(const QPointF &oldPos, const QPointF &newPos) const;
//跑道入侵检测
void runwayIncursionCheck(std::vector<OtherAircraftInfo> &aircraftInfo)
{for (std::vector<OtherAircraftInfo>::iterator itr = aircraftInfo.begin(); itr != aircraftInfo.end(); itr++){if (mCurrentRunWay.count() == 4){if (mCalculate.isInQuadrangle(mCurrentRunWay, QPointF(itr->lon, itr->lat))){itr->incursion = true;qWarning() << "Runway Incursion: " << itr->ID;}else{itr->incursion = false;}}		}
}
计算本机所在的跑道
void whichRunWay(const AircraftInfo & aircraftInfo)
{//foreach runWaymCurrentRunWay.clear();for (int runwayIndex = 0; runwayIndex < mRunWays.count() ; runwayIndex++){		QVector<QPointF> runWay(4);double angle = mCalculate.getAngle(mRunWays[runwayIndex].at(0), mRunWays[runwayIndex].at(1));  //calculate runway anglemCalculate.getQuadrangleVertex(mRunWays[runwayIndex].at(0), mRunWays[runwayIndex].at(1), angle , 60/1852.0, runWay);if (mCalculate.isInQuadrangle(runWay, QPointF(aircraftInfo.lon, aircraftInfo.lat))){mCurrentRunWay = runWay;}}
}
//通过一个已知坐标点、方位角、和距离,计算另一个点的经纬度坐标
void CalculatePositionByAngle(double & DestLat, double & DestLon, double orgLat, double orgLon, double distNM, double angle)
{double rad_lati = ToRadian(orgLat);double rad_longi = ToRadian(orgLon);double Ec = PolarRadiusMeter + (EquatorRadiusMeter - PolarRadiusMeter)*(90.0 - orgLat) / 90.0;double Ed = EquatorRadiusMeter * cos(rad_lati);double difx = distNM * 1852.0 * cos(ToRadian(90 - angle));double dify = distNM * 1852.0 * sin(ToRadian(90 - angle));DestLat = ToAngle(1.0*dify / Ec + rad_lati);DestLon = ToAngle(1.0*difx / Ed + rad_longi);if (DestLon > 180){DestLon = DestLon - 360;}if (DestLat > 180){DestLat = DestLat - 360;}
}
const qreal pi = 3.141592653589793238462643383;
//判断坐标点,是否在一个四边形区域内
bool isInQuadrangle(QVector<QPointF> &pointfs, QPointF p)
{double dTriangle = getTriangleArea(pointfs.at(0), pointfs.at(1), p) + getTriangleArea(pointfs.at(1), pointfs.at(2), p) + getTriangleArea(pointfs.at(2), pointfs.at(3), p) + getTriangleArea(pointfs.at(3), pointfs.at(0), p);double dQuadrangle = getTriangleArea(pointfs.at(0), pointfs.at(1), pointfs.at(2)) + getTriangleArea(pointfs.at(2), pointfs.at(3), pointfs.at(0));if ((dTriangle >0) && (dQuadrangle > 0) && (qAbs(dTriangle - dQuadrangle) < 0.00001)){qDebug() << "isInQuadrangle: " << qAbs(dTriangle - dQuadrangle);return true;}elsereturn false;//return dTriangle == dQuadrangle;
}
//计算一个三角形的面积
double getTriangleArea(QPointF p1, QPointF p2, QPointF p3)
{return qAbs((p1.x()*p2.y() + p2.x()*p3.y() + p3.x()*p1.y() - p2.x()*p1.y() - p3.x()*p2.y() - p1.x()*p3.y()) / 2.0);
}//根据四边形两条对边的中线,方位、宽度,计算出四个顶点坐标
void getQuadrangleVertex(QPointF m1, QPointF m2, float direction, double len, QVector<QPointF> &pointfs)
{float angle1 = 0.0;float angle2 = 0.0;angle1 = (direction + 90.0) > 360.0 ? direction + 90.0 - 360.0 : direction + 90.0;angle2 = (direction + 270.0) > 360.0 ? direction + 270.0 - 360.0 : direction + 270.0;Conversions cver;cver.CalculatePositionByAngle(pointfs[0].ry(), pointfs[0].rx(), m1.y(), m1.x(), len / 2, angle1);cver.CalculatePositionByAngle(pointfs[1].ry(), pointfs[1].rx(), m1.y(), m1.x(), len / 2, angle2);cver.CalculatePositionByAngle(pointfs[2].ry(), pointfs[2].rx(), m2.y(), m2.x(), len / 2, angle1);cver.CalculatePositionByAngle(pointfs[3].ry(), pointfs[3].rx(), m2.y(), m2.x(), len / 2, angle2);clockwiseSort(pointfs);
}//四边形四个顶点 按照顺时针排序
void clockwiseSort(QVector<QPointF>& vPoints)
{//calculate centre pointQPointF center;double x = 0, y = 0;for (int i = 0; i < vPoints.size(); i++){x += vPoints[i].x();y += vPoints[i].y();}center.rx() = (int)x / vPoints.size();center.ry() = (int)y / vPoints.size();//sort pointfor (int i = 0; i < vPoints.size(); i++){for (int j = 0; j < vPoints.size() - i - 1; j++){if (PointCmp(vPoints[j], vPoints[j + 1], center)){QPointF tmp = vPoints[j];vPoints[j] = vPoints[j + 1];vPoints[j + 1] = tmp;}}}
}bool PointCmp(const QPointF &a, const QPointF &b, const QPointF &center)
{if (a.x() >= 0 && b.x() < 0)return true;/*if (a.x() == 0 && b.x() == 0)return a.y() > b.y();*///向量OA和向量OB的叉积int det = (a.x() - center.x()) * (b.y() - center.y()) - (b.x() - center.x()) * (a.y() - center.y());if (det < 0)return true;if (det > 0)return false;//向量OA和向量OB共线,以距离判断大小int d1 = (a.x() - center.x()) * (a.x() - center.x()) + (a.y() - center.y()) * (a.y() - center.y());int d2 = (b.x() - center.x()) * (b.x() - center.y()) + (b.y() - center.y()) * (b.y() - center.y());return d1 > d2;
}
//根据两个点,计算方位
double getAngle(const QPointF &oldPos, const QPointF &newPos) const
{//根据两个点的经纬度,以一个点(old)为坐标中心,y轴正方向为正北方向(即为 0°),求出另一个点(new)关于正北方向的角度(0° ~ 360°)double a = newPos.x() - oldPos.x();  //经度差double b = newPos.y() - oldPos.y();    //纬度差double c = hypot(fabs(a), fabs(b));double cosy = 0.0;double angle = 0;if (a > 0 && b > 0)         // 判断road点在user点的东北位置{cosy = b / c;angle = 0;}else if ((a == 0) && (b > 0))  //在正北位置{angle = -90;}else if ((a > 0) && (b < 0))   // 判断road点在user点的东南位置{cosy = a / c;angle = 90;}else if ((a > 0) && (b == 0))  //在正东位置{angle = 90;}else if ((a < 0) && (b < 0))    // 判断road点在user点的西南位置{cosy = fabs(b) / c;angle = 180;}else if ((a == 0) && (b < 0))   //在正南位置{angle = 90;}else if ((a < 0) && (b > 0))    // 判断road点在user点的西北位置{cosy = fabs(a) / c;angle = 270;}else if ((a < 0) && (b == 0))   //在正西位置{angle = 180;}double m = acos(cosy);//n 即以正北为 0 的总角度double n = (m / pi) * 180 + angle;return n;
}

这篇关于机场跑道入侵检测(C++、Qt)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/166965

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

Linux系统性能检测命令详解

《Linux系统性能检测命令详解》本文介绍了Linux系统常用的监控命令(如top、vmstat、iostat、htop等)及其参数功能,涵盖进程状态、内存使用、磁盘I/O、系统负载等多维度资源监控,... 目录toppsuptimevmstatIOStatiotopslabtophtopdstatnmon

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

C++中NULL与nullptr的区别小结

《C++中NULL与nullptr的区别小结》本文介绍了C++编程中NULL与nullptr的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编... 目录C++98空值——NULLC++11空值——nullptr区别对比示例 C++98空值——NUL

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构