如何在二维平面中高效查找指定半径内的点

发布时间 - 2026-01-20 00:00:00    点击率:

本文介绍在二维直角坐标系中,通过“边界矩形预筛选 + 欧氏距离精筛”策略,快速定位某参考点指定半径内的所有邻近点,显著减少计算量,适用于php等通用编程环境。

在处理大量二维点(如 800×800 像素画布上的坐标数据)时,若对每个点都与其他全部点计算欧氏距离(时间复杂度 O(n²)),性能会随点数增长急剧下降。为提升效率,关键在于缩小候选集范围——即先用低成本操作快速排除明显超距的点,再对剩余少量候选点执行精确距离判断。

✅ 核心思想:两阶段筛选法

  1. 粗筛(O(1) per point):以目标点 (cx, cy) 为中心,构建边长为 2r 的正方形包围盒(即 x ∈ [cx−r, cx+r],y ∈ [cy−r, cy+r])。该操作仅需两次浮点比较,可瞬间过滤掉绝大多数远离区域的点。
  2. 精筛(O(1) per candidate):对落在包围盒内的点,再计算其到中心点的欧氏距离平方(避免开方运算):
    dist² = (x − cx)² + (y − cy)²
    若 dist² ≤ r²,则该点确实在圆内。
⚠️ 注意:直接比较 dist² 与 r² 而非 dist ≤ r,可完全规避耗时的 sqrt() 运算,进一步提升性能。

? PHP 实现示例

function findPointsInRadius($points, $centerX, $centerY, $radius) {
    $rSquared = $radius * $radius;
    $candidates = [];

    // 阶段一:矩形预筛选(快速排除)
    foreach ($points as $point) {
        $dx = $point['x'] - $centerX;
        $dy = $poin

t['y'] - $centerY; // 若超出正方形边界,跳过(绝对值比较比平方更快) if (abs($dx) > $radius || abs($dy) > $radius) { continue; } // 阶段二:欧氏距离平方精筛 $distSquared = $dx * $dx + $dy * $dy; if ($distSquared <= $rSquared) { $candidates[] = $point; } } return $candidates; } // 使用示例 $points = [ ['x' => 100, 'y' => 100], ['x' => 120, 'y' => 230], ['x' => 240, 'y' => 680], ['x' => 700, 'y' => 140], ]; $result = findPointsInRadius($points, 110, 105, 20); // 查找 (110,105) 半径20内的点 print_r($result);

? 进阶建议(当数据规模持续增大时)

  • 空间索引优化:若点集静态或更新不频繁,可预构建四叉树(Quadtree) 或使用 R-Tree 索引(如通过 SQLite R*Tree 扩展或 PostGIS),将查询复杂度降至接近 O(log n)。
  • 数据库层优化:若点存于 MySQL/PostgreSQL,可利用 WHERE x BETWEEN ? AND ? AND y BETWEEN ? AND ? 先走索引过滤,再用 SQRT(POW(x-?,2)+POW(y-?,2))
  • 避免常见误区:不要尝试用极坐标或角度划分,二维平面中矩形剪枝已是理论最优的低成本预判方式;也不必过早引入复杂算法——对数百至数千点,上述两阶段法已足够高效。

该方法兼顾简洁性、可读性与实用性,是二维平面邻域查询的经典工程解法。


# mysql  # php  # red  # 算法  # sqlite  # postgresql  # 数据库  # 低成本  # 进阶  # 浮点  # 中心点  # 两次  # 适用于  # 落在  # 已是  # 更快  # 数百 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 香港服务器如何优化才能显著提升网站加载速度?  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  如何快速查询网址的建站时间与历史轨迹?  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  利用vue写todolist单页应用  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  Windows Hello人脸识别突然无法使用  jQuery 常见小例汇总  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  微信h5制作网站有哪些,免费微信H5页面制作工具?  Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置  怎么用AI帮你为初创公司进行市场定位分析?  Laravel如何使用Vite进行前端资源打包?(配置示例)  如何挑选高效建站主机与优质域名?  如何实现建站之星域名转发设置?  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  公司网站制作需要多少钱,找人做公司网站需要多少钱?  如何在新浪SAE免费搭建个人博客?  微信小程序 require机制详解及实例代码  在线教育网站制作平台,山西立德教育官网?  Laravel怎么解决跨域问题_Laravel配置CORS跨域访问  Laravel如何实现API资源集合?(Resource Collection教程)  JS碰撞运动实现方法详解  如何选择PHP开源工具快速搭建网站?  Python企业级消息系统教程_KafkaRabbitMQ高并发应用  新三国志曹操传主线渭水交兵攻略  Java遍历集合的三种方式  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  javascript中的try catch异常捕获机制用法分析  bootstrap日历插件datetimepicker使用方法  Laravel如何实现一对一模型关联?(Eloquent示例)  如何快速生成ASP一键建站模板并优化安全性?  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  如何在IIS中新建站点并配置端口与IP地址?  javascript中闭包概念与用法深入理解  如何用y主机助手快速搭建网站?  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  利用JavaScript实现拖拽改变元素大小  如何用景安虚拟主机手机版绑定域名建站?  如何在阿里云高效完成企业建站全流程?  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法  如何在阿里云ECS服务器部署织梦CMS网站?  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  lovemo网页版地址 lovemo官网手机登录