C++ 存储二维点,以便快速检索矩形内的点

C++ 存储二维点,以便快速检索矩形内的点,c++,stl,boost,spatial,point,C++,Stl,Boost,Spatial,Point,我有大量的2D点,我想快速得到那些位于某个矩形中的点。 假设a'.'是任意点,'X'是我想在一个矩形内找到的点,该矩形的左上角点为'T',右下角点为'B' . . . . . . . T-----+ . . | X X | . . +-----B . . . . . . . 我尝试了一个带有排序函子的std::set,该函子在集合的开始处对左上角点进行排序,在集合的结尾处对右下角点进行排序。首先按X值排序时,这将导致找到以下几点 . . . . . . . T-----+ . X | X X

我有大量的2D点,我想快速得到那些位于某个矩形中的点。 假设a'.'是任意点,'X'是我想在一个矩形内找到的点,该矩形的左上角点为'T',右下角点为'B'

. . . . . .
. T-----+ .
. | X X | .
. +-----B .
. . . . . .
我尝试了一个带有排序函子的std::set,该函子在集合的开始处对左上角点进行排序,在集合的结尾处对右下角点进行排序。首先按X值排序时,这将导致找到以下几点

. . . . . .
. T-----+ .
X | X X | X
. +-----B .
. . . . . .
这意味着我必须检查每个找到的点,它是否真的在矩形内。不太好

有什么更好的方法可以做到这一点

<>我的语言是C++(Windows),我有STL以及Boost可用。 更新 阅读了到目前为止的答案后,我注意到我还没有考虑问题的所有参数:没有一个固定的矩形。 用户可以在运行时设置矩形。这意味着,按照Artelius在此次更新之前的建议,对点集进行排序比对所有点进行线性搜索更有效率。
不过,我还是要试试看!我不希望用户经常设置矩形。因此,关于实现工作,它可能对我来说是一个很好的解决方案。

您可以使用四叉树或r树将点存储在空间索引中。然后给定一个矩形,您可以找到树中所有与之重叠的节点,然后您必须比较该子集中的每个点,以查看它是否落在矩形中

本质上,空间树可以帮助您修剪搜索空间


您可能可以使用一个更简单的解决方案,例如在范围内对点进行分区。假设x是从0,10作为一个范围,11,20作为另一个范围。任何允许您修剪搜索空间的解决方案都会有所帮助。

使用四叉树,您有3种类型的qtree节点:

  • 节点位于目标矩形之外:忽略
  • 节点位于目标矩形内:包括节点内的所有点
  • 节点部分位于矩形外:对节点内的点执行边界检查
  • 请看。 在C++中实现了KDFISH的一些实现,
    尽管它们不是STL或Boost的一部分。

    您的排序函数可以在添加点时检查矩形内部的粗糙度,并在矩形外部的所有点之前对矩形内部的所有点进行排序。您必须跟踪每个存在的数量,或者在查找时对整个集合使用二进制搜索来查找截止点。

    根据Yuval F的链接,我找到了,这似乎正是您要查找的内容。我从那里找到了一些链接,发现了一个开源的C++库,它实现了一个范围搜索,并用例子。简单地单独检查每个点(不进行排序)需要O(n)个时间

    因此,只需检查每个点就比排序快。而且它比构建四叉树还要快


    编辑:如果你有很多矩形要检查,那就不同了。但是如果你只需要检查一个小的、固定数量的矩形,那么就用“明显”的方式来做吧

    如果你建立一个四叉树,你只做一次。那么你的搜索只有O(logn),这会更快。你的观点是什么?我在回答中已经提到了这一点。如果只需要检查一个矩形,那么构建四叉树的速度要慢得多。如果矩形四处移动,保持四叉树的最新状态也会占用大量时间。