找到两个多边形之间最短笛卡尔距离的最快方法是什么

时间:2008-09-17 14:48:14

标签: c# algorithm gis polygon distance

我有 1个红色多边形说和 50个随机放置的蓝色多边形 - 它们位于地理 2D空间中。找到红色多边形与其最近的蓝色多边形之间的最短距离,最快/最快的算法是什么?

请记住,将构成多边形顶点的点作为测试距离的值并不是一个简单的例子,因为它们可能不一定是最接近的点。

所以最后 - 答案应该将最接近的蓝色多边形返回到单一的红色多边形。

这比听起来更难!

13 个答案:

答案 0 :(得分:14)

我怀疑有更好的解决方案,而不是计算红色和蓝色之间的距离,并按长度排序。

关于排序,通常QuickSort在性能方面很难被击败(优化的一个,如果大小低于7个项目并切换到类似InsertionSort,可能是ShellSort,则会切断递归。)

因此,我想问题是如何快速计算两个多边形之间的距离,毕竟你需要进行50次这样的计算。

以下方法也适用于3D,但可能不是最快的方法:

Minimum Polygon Distance in 2D Space

问题是,您是否愿意以准确性换取速度?例如。您可以将所有多边形打包到边界框中,其中框的边与坐标系轴平行。 3D游戏经常使用这种方法。因此,您需要找到每个坐标(x,y,z)的最大值和最小值,以构建虚拟边界框。计算这些边界框的距离是一项非常简单的任务。

以下是更高级边界框的示例图像,它与坐标系轴不平行:

Oriented Bounding Boxes - OBB

然而,这使得距离计算不那么简单。它用于碰撞检测,因为您不需要知道它的距离,您只需要知道一个边界框的一个边是否位于另一个边界框内。

下图显示了一个轴对齐的边界框:

Axes Aligned Bounding Box - AABB

OOB更准确,AABB更快。也许你想阅读这篇文章:

Advanced Collision Detection Techniques

这总是假设您愿意以精确度换取速度。如果精度比速度更重要,那么您可能需要更先进的技术。

答案 1 :(得分:5)

您可以减少问题,然后在一小部分上进行密集搜索。

首先通过查找:

处理每个多边形
  • 多边形中心
  • 多边形的最大半径(即,距离定义的中心最远的多边形的边缘/表面/顶点上的点)

现在你可以收集5-10个最近的多边形到红色的多边形(找到距离中心到中心,减去半径,对列表进行排序并取前5个),然后做一个更详尽的例行程序。

答案 2 :(得分:4)

对于具有合理数量边界点的多边形形状,例如在GIS或游戏应用程序中,可能更容易进行一系列测试。

对于红色多边形中的每个顶点,计算到蓝色多边形中每个顶点的距离并找到最近的(提示,比较距离^ 2,因此您不需要sqrt()) 找到最近的,然后检查找到的红色和蓝色顶点每一侧的顶点,以确定哪个线段最接近,然后找到两个线段之间最接近的方法。

请参阅http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/(对于2d案例来说很简单)

答案 3 :(得分:3)

答案 4 :(得分:3)

此筛选技术旨在减少您在平均情况下需要执行的距离计算的数量,而不会影响结果的准确性。它适用于凸多边形和凹多边形。

找到每对顶点之间的最小距离,使得一个是红色顶点,一个是蓝色。称之为 r 。多边形之间的距离最多为 r 。从红色多边形构造一个新区域,其中每个线段通过 r 向外移动,并通过半径为 r 的圆弧连接到其邻居,并以顶点为中心。找到该区域内每个顶点到与该区域相交的相反颜色的每个线段的距离。

当然,您可以添加一个近似方法,例如边界框,以快速确定哪些蓝色多边形不可能与红色区域相交。

答案 5 :(得分:2)

我知道你说过“最短距离”,但你真的意味着最佳解决方案或“好/非常好”的解决方案对你的问题没问题吗?

因为如果需要找到最佳解决方案,则必须计算所有源和目标poligon边界(不仅是顶点)之间的距离。如果你在3D空间,那么每个边界都是一个平面。这可能是个大问题(O(n ^ 2)),取决于你有多少个顶点。

因此,如果您有顶点计数使得这些正方形变为疤痕数并且“好/非常好”的解决方案对您来说没问题,那么请寻找启发式解决方案或近似值。

答案 6 :(得分:2)

你可能想看看Voronoi Culling。论文和视频:

http://www.cs.unc.edu/~geom/DVD/

答案 7 :(得分:2)

我首先要通过一个边界圆来限制所有多边形,然后找到最小距离的上限。 然后我会简单地检查所有蓝色多边形的边缘,其距离的下限低于红色多边形的所有边缘的最小距离的上限。

upper bound of min distance = min {distance(red's center, current blue's center) + current blue's radius}

for every blue polygon where distance(red's center, current blue's center) - current blue's radius < upper bound of min distance
    check distance of edges and vertices

但这一切都取决于你的数据。如果蓝色多边形与它们与红色多边形之间的距离相比相对较小,那么这种方法应该可以很好地工作,但是如果它们非常接近,则不会保存任何东西(其中许多将足够接近)。还有一件事 - 如果这些多边形没有很多顶点(比如大多数是三角形),那么只需要检查每个红色边缘对每个蓝色边缘的速度几乎一样快。

希望有所帮助

答案 8 :(得分:2)

正如其他人所提到的,使用边界区域(方框,圆圈)可能允许您丢弃一些多边形 - 多边形交互。有几种策略,例如

  1. 选择任何蓝色多边形并找到红色多边形的距离。现在选择任何其他多边形。如果边界区域之间的最小距离大于已找到的距离,则可以忽略此多边形。继续所有多边形。
  2. 找到红色多边形与所有蓝色多边形之间的最小距离/质心距离。对距离进行排序并首先考虑最小距离。计算实际最小距离并继续排序列表,直到多边形之间的最大距离大于到目前为止找到的最小距离。
  3. 您选择的圆/轴对齐框或方向框会对算法的性能产生很大影响,具体取决于输入多边形的实际布局。

    对于实际的最小距离计算,您可以使用Yang等人的“A new fast algorithm for computing the distance between two disjoint convex polygons based on Voronoi diagram”,即O(log n + log m)。

答案 9 :(得分:2)

要在一秒钟内跑去参加葬礼,但是如果你把多边形分成凸出的子弹,你可以做一些优化。您可以对每个多边形进行二进制搜索以找到最近的顶点,然后我相信最近的点应该是该顶点或相邻边。这意味着您应该能够在log(log m * n)中执行此操作,其中m是poly上的平均顶点数,n是polies的数量。这有点匆忙,所以可能是错的。如果需要,将在稍后提供更多细节。

答案 10 :(得分:1)

您可以从比较边界框之间的距离开始。测试矩形之间的距离比测试多边形之间的距离更容易,并且您可以立即消除任何超过nearest_rect + its_diagonal的多边形(可能您可以进一步细化)。然后,您可以测试剩余的多边形以找到最接近的多边形。

有找到多边形接近度的算法 - 我确信维基百科对它们有很好的评价。如果我没记错的话,那些只允许凸多边形的东西要快得多。

答案 11 :(得分:0)

我相信你要找的是A *算法,它用于寻路。

答案 12 :(得分:-1)

天真的方法是找到红色和50个蓝色物体之间的距离 - 所以你要看50个三维毕达哥拉斯计算+排序找到答案。这只能找到中心点之间的距离。

如果你想要任意多边形,也许最好的是光线跟踪解决方案,它从红色多边形的表面发射相对于法线的光线,并报告何时击中另一个多边形。

混合可能有效 - 我们可以找到距离中心点的距离,假设我们对蓝色多边形的相对大小有一些概念,我们可以将结果集剔除到最接近的那些,然后使用光线追踪缩小沿着真正最近的多边形。

相关问题