当前位置: 首页 > backend >正文

在 Qt/C++ 中查找最近点并截断 QVector<QPointF>

本文将详细介绍如何在 Qt/C++ 中处理点集数据,包括查找距离特定点最近的点,并以该点为分界点截断数据。我们将提供完整、独立的代码示例,并深入探讨相关数学原理和实现细节。

问题描述

给定一个点集 QVector<QPointF> 和一个目标点 (a,r2−a2)(a, \sqrt{r^2 - a^2})(a,r2a2),我们需要:

  1. 找到点集中距离目标点最近的点
  2. 以该最近点为分界点,获取其后半部分点集
  3. 保持原始数据不变

数学基础

计算两点 (x1,y1)(x_1, y_1)(x1,y1)(x2,y2)(x_2, y_2)(x2,y2) 之间的距离使用欧几里得距离公式:

d=(x2−x1)2+(y2−y1)2d = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2}d=(x2x1)2+(y2y1)2

在实际编程中,我们通常比较平方距离以避免耗时的开方运算:

d2=(x2−x1)2+(y2−y1)2d^2 = (x_2 - x_1)^2 + (y_2 - y_1)^2d2=(x2x1)2+(y2y1)2

完整实现

1. 查找最近点

#include <QVector>
#include <QPointF>
#include <cmath>
#include <algorithm>
#include <QDebug>QPointF findNearestPoint(const QVector<QPointF>& points, double a, double r) {if (points.isEmpty()) {return QPointF(); // 返回无效点}// 计算目标点QPointF targetPoint(a, std::sqrt(r * r - a * a));// 定义平方距离计算函数auto distanceSquared = const QPointF& point {double dx = point.x() - targetPoint.x();double dy = point.y() - targetPoint.y();return dx * dx + dy * dy;};// 查找最近点auto nearestIt = std::min_element(points.begin(), points.end(),const QPointF& p1, const QPointF& p2 {return distanceSquared(p1) < distanceSquared(p2);});return *nearestIt;
}// 示例用法
void demoFindNearestPoint() {QVector<QPointF> points = {QPointF(1.0, 2.0),QPointF(3.0, 4.0),QPointF(5.0, 6.0)};double a = 2.0;double r = 5.0;QPointF nearest = findNearestPoint(points, a, r);qDebug() << "Nearest point:" << nearest;
}

2. 获取后半部分点集

#include <QVector>
#include <QPointF>
#include <cmath>
#include <algorithm>
#include <QDebug>QVector<QPointF> getSecondHalfFromNearest(const QVector<QPointF>& points, double a, double r) {if (points.isEmpty()) {return QVector<QPointF>();}QPointF targetPoint(a, std::sqrt(r * r - a * a));auto distanceSquared = const QPointF& point {double dx = point.x() - targetPoint.x();double dy = point.y() - targetPoint.y();return dx * dx + dy * dy;};auto nearestIt = std::min_element(points.begin(), points.end(),const QPointF& p1, const QPointF& p2 {return distanceSquared(p1) < distanceSquared(p2);});// 使用范围构造函数创建新向量return QVector<QPointF>(nearestIt, points.end());
}// 示例用法
void demoGetSecondHalf() {QVector<QPointF> points = {QPointF(1.0, 1.0),QPointF(2.0, 2.0),QPointF(3.0, 3.0),QPointF(4.0, 4.0)};double a = 1.5;double r = 2.5;QVector<QPointF> secondHalf = getSecondHalfFromNearest(points, a, r);qDebug() << "Second half points:";for (const QPointF& p : secondHalf) {qDebug() << p;}
}

3. 高级用法:获取最近点及其索引

#include <QVector>
#include <QPointF>
#include <cmath>
#include <algorithm>
#include <utility>
#include <QDebug>std::pair<QPointF, int> findNearestWithIndex(const QVector<QPointF>& points, double a, double r) {if (points.isEmpty()) {return {QPointF(), -1};}QPointF targetPoint(a, std::sqrt(r * r - a * a));auto distanceSquared = const QPointF& point {double dx = point.x() - targetPoint.x();double dy = point.y() - targetPoint.y();return dx * dx + dy * dy;};auto nearestIt = std::min_element(points.begin(), points.end(),const QPointF& p1, const QPointF& p2 {return distanceSquared(p1) < distanceSquared(p2);});int index = nearestIt - points.begin();return {*nearestIt, index};
}// 示例用法
void demoFindNearestWithIndex() {QVector<QPointF> points = {QPointF(1.0, 1.0),QPointF(2.0, 2.0),QPointF(3.0, 3.0)};double a = 2.5;double r = 3.5;auto [point, index] = findNearestWithIndex(points, a, r);qDebug() << "Nearest point:" << point << "at index:" << index;
}

技术细节分析

1. 距离计算优化

我们使用平方距离进行比较而非实际距离,因为:

  1. 避免耗时的 std::sqrt 运算
  2. 平方保持单调性,比较结果与真实距离一致
  3. 在大多数情况下足够满足需求

d2=(x2−x1)2+(y2−y1)2d^2 = (x_2 - x_1)^2 + (y_2 - y_1)^2d2=(x2x1)2+(y2y1)2

2. 迭代器与索引

Qt 容器同时支持迭代器和索引访问:

  • 迭代器:更符合 STL 风格,适用于算法操作
  • 索引:更直观,便于调试和特定位置访问

转换关系:

int index = iterator - container.begin();
auto iterator = container.begin() + index;

3. 边界情况处理

代码中处理了以下边界情况:

  1. 空输入容器
  2. 目标点计算可能产生 NaN(当 r2<a2r^2 < a^2r2<a2 时)
  3. 多个点距离相同(返回第一个遇到的点)

性能考虑

  1. 时间复杂度O(n)O(n)O(n),需要遍历整个容器查找最近点
  2. 空间复杂度O(m)O(m)O(m),其中 mmm 是后半部分的点数
  3. 优化建议
    • 对大型数据集考虑空间索引结构(如 k-d 树)
    • 如果需要频繁查询,可以预先计算并缓存距离

实际应用示例

假设我们有一个路径规划应用,需要找到距离某个关键位置最近的路点,并分析后续路径:

#include <QVector>
#include <QPointF>
#include <cmath>
#include <algorithm>
#include <QDebug>void pathPlanningExample() {// 模拟GPS轨迹点QVector<QPointF> trajectory = {QPointF(116.404, 39.915),  // 北京QPointF(121.474, 31.230),  // 上海QPointF(113.264, 23.129),  // 广州QPointF(114.109, 22.396)   // 深圳};// 目标点:香港大致坐标double a = 114.177;double r = 0.5; // 搜索半径(简化)// 查找最近点auto [nearestPoint, index] = findNearestWithIndex(trajectory, a, r);qDebug() << "Nearest waypoint to Hong Kong:" << nearestPoint << "at index" << index;// 获取后续路径QVector<QPointF> remainingPath(trajectory.begin() + index, trajectory.end());qDebug() << "Remaining path points:";for (const QPointF& p : remainingPath) {qDebug() << p;}
}

总结

本文详细介绍了在 Qt/C++ 中处理点集数据的完整方案,包括:

  1. 数学原理:距离计算公式及优化
  2. 完整代码实现:三个独立可运行的示例
  3. 技术细节:迭代器使用、边界处理、性能分析
  4. 实际应用示例

这些技术可以广泛应用于:

  • 地理信息系统 (GIS)
  • 路径规划和导航
  • 计算机视觉中的特征点处理
  • 游戏开发中的AI路径寻找

关键点在于理解距离计算原理和 Qt 容器的操作方式,通过合理使用 STL 算法和 Qt 提供的功能,可以高效地解决这类空间数据处理问题。

http://www.xdnf.cn/news/19454.html

相关文章:

  • 驱动——miscdevice框架 vs 标准字符设备cdev框架
  • Android开发之add方式添加Fragment生命周期不响应
  • 单例模式
  • Selenium 自动化测试实战:绕过登录直接获取 Cookie
  • 希尔排序。
  • Java面试-微服务(业务问题)
  • QT控件QPlainTextEdit、QTextEdit与QTextBrowser的区别
  • 【秋招笔试】2025.08.31小红书秋招笔试真题
  • 解读数据中台建设汇报方案【附全文阅读】
  • 淘天二面总结
  • 链表算法知识汇总
  • lesson51:CSS全攻略:从基础样式到前沿特性的实战指南
  • 【读论文】量子关联增强双梳光谱技术
  • RabbitMinQ(模拟实现消息队列项目)02
  • 【零碎小知识点 】(四) Java多线程编程深入与实践
  • Spring Cloud ------ Gateway
  • 阿里Qoder怎么样?实测对比TRAE SOLO 和 CodeBuddy IDE
  • 【甲烷数据集】全球逐日无缝隙柱平均干空气甲烷浓度(XCH₄)
  • Solid Explorer文件管理器:功能强大的安卓文件管理器及网盘文件管理器
  • FFMPEG AAC
  • 【MySQL详解】索引、事务、锁、日志
  • 【MySQL基础】MySQL核心操作全解析
  • GPT - 5 技术前瞻与开发者高效接入路径探索​
  • Java-113 深入浅出 MySQL 扩容全攻略:触发条件、迁移方案与性能优化
  • Java实现图像像素化
  • VirtualBox7.2安装步骤
  • RT-DETR网络结构
  • 开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信
  • LangChain VectorStores核心:多向量数据库统一交互层与RAG存储中枢
  • 云原生新手入门完整学习指南