机场跑道入侵检测(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

相关文章

Qt实现发送HTTP请求的示例详解

《Qt实现发送HTTP请求的示例详解》这篇文章主要为大家详细介绍了如何通过Qt实现发送HTTP请求,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、添加network模块2、包含改头文件3、创建网络访问管理器4、创建接口5、创建网络请求对象6、创建一个回复对

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

C++一个数组赋值给另一个数组方式

《C++一个数组赋值给另一个数组方式》文章介绍了三种在C++中将一个数组赋值给另一个数组的方法:使用循环逐个元素赋值、使用标准库函数std::copy或std::memcpy以及使用标准库容器,每种方... 目录C++一个数组赋值给另一个数组循环遍历赋值使用标准库中的函数 std::copy 或 std::

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

C++初始化数组的几种常见方法(简单易懂)

《C++初始化数组的几种常见方法(简单易懂)》本文介绍了C++中数组的初始化方法,包括一维数组和二维数组的初始化,以及用new动态初始化数组,在C++11及以上版本中,还提供了使用std::array... 目录1、初始化一维数组1.1、使用列表初始化(推荐方式)1.2、初始化部分列表1.3、使用std::

C++ Primer 多维数组的使用

《C++Primer多维数组的使用》本文主要介绍了多维数组在C++语言中的定义、初始化、下标引用以及使用范围for语句处理多维数组的方法,具有一定的参考价值,感兴趣的可以了解一下... 目录多维数组多维数组的初始化多维数组的下标引用使用范围for语句处理多维数组指针和多维数组多维数组严格来说,C++语言没

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

c++中std::placeholders的使用方法

《c++中std::placeholders的使用方法》std::placeholders是C++标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴... 目录1. 基本概念2. 使用场景3. 示例示例 1:部分参数绑定示例 2:参数重排序4. 注意事项5.