给定 voronoi 图的生成点;计算它的顶点

问题描述

让 $p_i$ 成为二维空间中的第 i 个点,生成 voronoi 图。这意味着,Voronoi 区域 $V_i$ 中的每个点 $x$ 满足

$|x-p_i|

和 $|x-p_i|=|x-p_j|,i \neq j$ 在其边界上。边界是具有顶点和边的图。现在我对跨越 Voronoi 图的边界(边)的顶点的位置感兴趣。

当我选择 $p_i$ 时,有哪些算法可以计算 Voronoi 图的顶点位置?

我知道我可以搜索 $p_i$ 的最近邻生成器,​​然后使用外接圆属性;但是我怎样才能尽可能有效地找到最近邻居的位置(意味着我已经找到了 delaunay 三角剖分)?

请注意,我对如何找到位于分隔 Voronoi 区域的边界上的顶点(边界的三个边相交处)的坐标向量 $(r_x,r_y)$ 感兴趣。有什么提示吗?

解决方法

不幸的是,最佳解决方案很复杂。

您可以使用 Fortune 或 Guibas & Stolfi 算法构建图表,这需要 O(N Log N) 时间和 O(N) 空间。 (由于 Voronoi 图和 Delaunay 三角剖分是彼此的对偶,您可以交替构造一个或另一个。)

但是 Voronoi 图的表示不适合任意点的有效定位。因此,您必须将其转换为梯形图等结构,这样可以在 O(Log N) 时间内进行高效的点位置查询。不幸的是,我从未见过在 Voronoi 图的框架中执行这种转换的显式算法。

,

计算平面中的 Voronoi 区域相当于计算 n 半平面的交点 - 由点 p_i 和每隔一个点 {{1} 之间的平分线定义的半平面}}。 然而,这个问题等价于(通过对偶)计算平面中 p_j 点的凸包(参见离散和计算几何手册中的 Chapter 30.5 on Arrangements)。 计算 n 的平面 has a known lower bound 中一组点的凸包。

计算 Delaunay 三角剖分只需要 \Omega(n log n) 时间。 因此,正如@matt-timmermans 和@yves-daoust 所建议的那样,将输入预处理为 Delaunay 三角剖分并不会产生真正的开销,并且可能是大多数应用程序的最佳选择。

一旦 Delaunay 三角剖分被计算出来,每个查询(区域边界的构建) 只需要 O(n log n) 时间,其中 O(1 + k) 是输出大小,即 Voronoi 区域边界上的顶点/边数。 请注意,k 本身可以是 k,例如,如果 \Omega(n) 点或多或少放置在一个圆上并且 n-1 靠近其中心。

虽然最坏情况的算法是 p_i,因此并不比计算 Delaunay 三角剖分更好, 还有一个输出敏感算法的选项,它采用 \Omega(n log n)(取决于输出 Voronoi 区域的大小)。

在Voronoi区域的边界上寻找单个顶点等价于线性规划问题的结果 (参见Computational Geometry: Algorithms and Applications的第 4 章)。

特别是,Megiddo 的算法或其随机版本(上述书籍的第 4.4 章)在 O(n*k) 线性时间内运行。 一旦找到带有两条生成线的第一个顶点,就可以通过将剩余的线与生成线相交来找到下一个顶点。 最近的交点是下一个 Voronoi 顶点,最近的相交线成为下一条相交的线。 当再次到达第一个顶点时,该过程终止。 总而言之,每次迭代需要 O(n),并且有 O(n) 次迭代,因此该算法总共需要 k