C++ 求点到多边形最近边距离的快速方法

C++ 求点到多边形最近边距离的快速方法,c++,algorithm,polygon,quadtree,r-tree,C++,Algorithm,Polygon,Quadtree,R Tree,设置 函数需要提供从点到多边形最近边的距离 已知该点位于多边形的内部 多边形可以是凸的也可以是凹的 许多点(百万)需要测试 每个点都需要通过函数运行许多单独的多边形(几十个) 预先计算和持久存储的数据结构是一种选择 最终搜索功能将使用C语言++ 对于函数实现,我知道一个简单的方法是使用标准的直线段距离公式测试到多边形所有段的距离。这个选择在规模上会相当缓慢,我相信会有更好的选择 我的直觉是,对于这种类型的函数,应该有一些已知的非常快的算法,可以在游戏引擎中实现,但我不确定该去哪里寻找 我找到

设置

  • 函数需要提供从点到多边形最近边的距离
  • 已知该点位于多边形的内部
  • 多边形可以是凸的也可以是凹的
  • 许多点(百万)需要测试
  • 每个点都需要通过函数运行许多单独的多边形(几十个)
  • 预先计算和持久存储的数据结构是一种选择
  • 最终搜索功能将使用C语言++
对于函数实现,我知道一个简单的方法是使用标准的直线段距离公式测试到多边形所有段的距离。这个选择在规模上会相当缓慢,我相信会有更好的选择

我的直觉是,对于这种类型的函数,应该有一些已知的非常快的算法,可以在游戏引擎中实现,但我不确定该去哪里寻找

我找到了一个在四叉树中存储线段的参考,这将提供非常快速的搜索,我认为它可以用于我的目的,快速缩小哪个线段是最近的线段,然后只需要计算到一个线段的距离。

我还没有找到任何代码示例来说明这是如何工作的。我不介意从头开始实现算法,但是如果存在一个工作的、经过测试的代码库,我不认为这样做有什么意义

我一直在研究几个四叉树实现,我认为它的工作方式是为每个多边形创建一个四叉树,并将每个多边形的线段和边界框插入到该多边形的四叉树中

我将要进行的函数的“查询”部分将包括创建一个点作为一个非常小的边界框,然后使用该边界框搜索四叉树结构,该结构将只查找多边形的最接近部分

我真正的问题是,对于快速搜索时间函数,这似乎是一种合理的方法吗

有什么东西可以更快地工作吗

编辑: 我四处查看,发现使用四叉树存在一些问题。四叉树的工作方式有利于碰撞检测,但其设置不允许有效的最近邻搜索。

R树看起来是一个更好的选择。


根据这些帖子,R树看起来像是赢家。也方便看到C++的Boost已经实现了它们。这看起来与我计划做的非常接近,我将继续实施它并验证结果。

我不确定你提出的四叉树算法有多好,所以我会让其他人对此发表评论,但我有一个想法,可能是快速和健壮的

我的想法是,你可以用KD树来表示一个多边形(假设顶点在时间上是静态的),然后找到最近的两个顶点,进行最近邻搜索,找到位于这个多边形中的任何点。如果我的想法是正确的,这两个顶点应该是创建最近线段的顶点,而不考虑凸性

编辑: 因为我已经实现了一个PMR四叉树,我现在看到,最近邻搜索比我描述的要复杂一些。 如果搜索点的四元搜索结果为空,则会变得更复杂。 我记得Hannan Sammets中有一个描述:多维搜索结构。 给出下面的答案时,我想搜索指定距离内的所有对象。这对于PMR四叉树来说很容易,但是仅仅找到最近的一个更复杂。 编辑结束

我不会使用R树。
R-树的弱点(和优点!)是将空间分割成矩形。
已知有三种算法可以实现这种分离,但没有一种算法适合所有情况。 R树的实现非常复杂。 那么为什么要这样做呢?仅仅因为R-树在完美实现时可以比四叉树快两倍。四叉树和R-树之间的速度差并不相关。货币差异是巨大的。(如果两者都有工作代码,我将使用PMR四叉树,如果只有R-树的代码,则使用该代码,如果没有,则使用PMR四叉树)

四叉树(PMR)总是有效的,而且它们很容易实现

使用PMR四叉树,您只需查找与搜索点相关的所有线段。结果将是一些片段,然后您只需检查它们,就可以准备好了

告诉四叉树不适合或邻居搜索的人不知道有数百种不同的四叉树。不适用性只适用于点四叉树,而不适用于存储边界框的PMR树

我曾经记得compelx关于在点四叉树中查找相邻点的描述。对于PMR四叉树,我无事可做(对于指定矩形间隔内的搜索),没有代码更改,只需迭代结果并找到最近的


我认为对于你的特定问题,有比四叉树或R-树更好的解决方案,但关键是PMR总是有效的。只需执行一次,在所有的空间搜索中使用。

< P>因为要测试的点比多边形要多很多,所以可以考虑对多边形进行相当广泛的预处理,以便加速平均测试次数以找到每个点最近的线段。 考虑这样一种方法(假设多边形没有孔):

  • 沿多边形的边漫游,并沿每条等距线定义线段
  • 测试线段的哪一侧是限制最近线段的潜在集合的点
  • 构建一个算术编码树,每个测试都根据测试的半个空间剔除的空间量进行加权