我有1个红色多边形和50个随机放置的蓝色多边形 - 它们位于地理的2D空间中。什么是最快/最快的算法来查找红色多边形与其最近的蓝色多边形之间的最短距离?
请注意,这不是简单地将构成多边形顶点的点作为要测试距离的值,因为它们可能不一定是最近的点。
因此,最终答案应该返回最接近的蓝色多边形到单个红色多边形。
这比听起来要难!
我有1个红色多边形和50个随机放置的蓝色多边形 - 它们位于地理的2D空间中。什么是最快/最快的算法来查找红色多边形与其最近的蓝色多边形之间的最短距离?
请注意,这不是简单地将构成多边形顶点的点作为要测试距离的值,因为它们可能不一定是最近的点。
因此,最终答案应该返回最接近的蓝色多边形到单个红色多边形。
这比听起来要难!
我认为没有比计算红色多边形与每个蓝色多边形之间的距离并按长度排序更好的解决方案。
关于排序,通常情况下,在性能方面很难超越快速排序(优化后,如果大小小于7个项,则切断递归并切换到类似插入排序的算法,例如希尔排序)。
因此,我认为问题是如何快速计算两个多边形之间的距离,毕竟您需要进行50次此类计算。
以下方法也适用于3D,但可能不是最快的:
问题是,您是否愿意为速度而牺牲准确性?例如,您可以将所有多边形打包到包围盒中,其中盒子的边与坐标系轴平行。 3D游戏经常使用这种方法。因此,需要找到每个坐标(x、y、z)的最大和最小值来构建虚拟包围盒。然后计算这些包围盒之间的距离就是一个相当简单的任务。
以下是更高级的包围盒的示例图像,它们不与坐标系轴平行:
但是,这使得距离计算变得更加复杂。它用于碰撞检测,因为您不需要知道距离,只需要知道一个包围盒的边是否位于另一个包围盒内。
以下图像显示了轴对齐包围盒:
OBB更精确,AABB更快。也许您想阅读这篇文章:
这总是假设你愿意为了速度而牺牲精度。如果精度比速度更重要,你可能需要使用更高级的技术。
您可以先尝试减少问题规模,然后对小规模数据进行深入搜索。
首先处理每个多边形,找到以下内容:
现在您可以收集与红色多边形最近的5-10个多边形(找到中心点之间的距离,减去半径,排序并选择前5个),然后执行更加详尽的例程。
对于具有合理数量边界点的多边形形状,例如在GIS或游戏应用中,可能更快更容易地进行一系列测试。
对于红色多边形中的每个顶点,计算到蓝色多边形中每个顶点的距离,并找到最近的(提示:比较distance^2,因此您不需要sqrt())。 找到最近的点后,检查找到的红色和蓝色顶点两侧的顶点,以决定哪些线段最接近,然后找到两条线段之间的最接近点。
请参见http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline3d/(它易于简化为2d情况)。
最小距离的上限 = min {distance(red的中心, 当前蓝色的中心) + 当前蓝色的半径}但这一切都取决于您的数据。如果相较于它们之间和红色多边形之间的距离,蓝色多边形相对较小,那么这种方法应该能够很好地工作,但是如果它们非常接近,您将无法节省任何东西(许多多边形将足够接近)。另外一件事情是,如果这些多边形没有许多顶点(就像大多数都是三角形),那么仅检查每个红色边界与每个蓝色边界的距离可能几乎一样快。
对于每个蓝色多边形,其中 distance(red的中心, 当前蓝色的中心) - 当前蓝色的半径 < 最小距离的上限 检查边缘和顶点的距离
我马上要去参加葬礼了,但是如果你将多边形分解为凸子多边形,就可以进行一些优化。你可以对每个多边形进行二分搜索,找到最近的顶点,然后我相信最近的点应该是那个顶点或相邻边上的点。这意味着你应该能够在log(log m * n)
的时间内完成,其中m是多边形上平均顶点数,n是多边形数。这有点匆忙,所以可能不正确。如果需要,稍后会提供更多详细信息。
我知道你说的是“最短距离”,但你真正想要的是最优解或者“好的/非常好的”解决方案,对吗?
因为如果你需要找到最优解,你必须计算所有源和目标多边形边界之间的距离(不仅仅是顶点)。如果你处在三维空间中,那么每个边界都是一个平面。这可能是一个大问题(O(n^2)),取决于你有多少个顶点。
所以,如果你的顶点数量使得计算结果很大,并且“好的/非常好的”解决方案对你来说足够了,那么可以使用启发式方法或近似方法。