# Voronoi Diagram 基础讲解
# 什么是 Voronoi Diagram?
给定一个点集 ,Voronoi 图是将平面划分为 个区域(称为 Voronoi Cells),每个区域对应一个点 ,使得该区域中任意一点 满足:
通俗来说,想象你在一个城市里有很多咖啡店,Voronoi 图的作用就是把整个城市划分成若干区域,每个区域内的所有人,走路距离都最接近某一家咖啡店。换句话说,它告诉你「谁最靠近谁」。
# Voronoi Diagram 的基本构成
- Voronoi Cell:每个点 的最近邻域。
- Voronoi Edge:两个 Voronoi cell 的公共边,即两个点的中垂线的一部分。
- Voronoi Vertex:三个或更多 Voronoi cell 的交点,等距于对应的点。
# 图示结构:
1 | Voronoi Vertex |
# 基本性质
- 连通性:Voronoi 图是连通图。
- 边类型:Voronoi Edge 是线段或射线(半无限长),除非所有点共线。
- 复杂度:
- Voronoi 顶点数:最多
- Voronoi 边数:最多
- 结论:总复杂度是线性的
# 空圆性质(Empty Circle Property)
# Voronoi 顶点的判定:
一个点 是 Voronoi 顶点 ⟺ 存在一个最大空圆 ,其边界上恰好有三个点 ,且圆内部不包含其它点。
# Voronoi 边的判定:
两点 之间存在 Voronoi 边 ⟺ 在它们的中垂线上存在点 ,其最大空圆仅以 为边界点。
# 应用举例
- 疫情分析(如 John Snow 的霍乱图)
- 最近邻搜索(NN、kNN)
- 地理信息系统(GIS)
- 图像处理与分割
- 网络规划(如通信塔覆盖区域)
- 机器学习中的聚类(如 K-means)
# Voronoi 图复杂度的欧拉公式证明
我们希望证明:对于 个点的 Voronoi 图 ,其复杂度是线性的:
- 顶点数
- 边数
# 📐 使用欧拉公式
欧拉公式是平面图中的基本定理:
其中:
- 是顶点数
- 是边数
- 是面数(Voronoi cell 数量,即原始点数 )
# 🔧 添加虚拟点使图封闭
由于 Voronoi 图的某些边是无穷延伸的半线,不能直接套用欧拉公式。为了解决这个问题,我们:
- 添加一个虚拟点
- 将所有半线连到 ,使图成为封闭图
这样我们有一个新的图,满足欧拉公式:
# 🔁 顶点度数下界
Voronoi 图中的每个顶点(包括新增的 )至少有 度数为 3,因为:
- 一个 Voronoi 顶点是三个 Voronoi cell 的交点
- 所以它至少连接三条边
因此:
- 所有顶点度数之和
- 而总度数也等于
所以:
# 🔚 代入欧拉公式
将上式代入公式 (*):
再代入 得:
# ✅ 结论
- 边数
- 顶点数
- Voronoi 图总结构复杂度为 (线性)
# Voronoi Diagram 的计算方法详解
Voronoi 图的计算,目标是将一组平面点划分成最近邻区域。虽然定义简单,但构造算法非常讲究效率和几何处理的技巧。
# 一、常见算法概览
算法 | 时间复杂度 | 核心思想 |
---|---|---|
增量式构造(Incremental) | 最坏 ,随机化期望 | 一个点一个点插入,逐步更新结构 |
扫描线法(Sweep Line / Fortune’s Algorithm) | 用一条从左往右移动的 “海滩线” 维护结构 | |
分治法(Divide and Conquer) | 分别处理左右子集,合并时找出分界线 | |
提升法(Lifting / 3D Convex Hull) | 把二维问题变为三维凸包问题再投影回二维 |
# 二、Incremental Algorithm(增量式)
# 思路:
- 初始 Voronoi 图为空或为第一个点占据全平面。
- 逐个插入点 ,在当前结构中找到属于 的区域。
- 更新 Voronoi 图:以 为中心构造新的边和顶点,修剪旧区域。
- 不断重复,直到所有点都插入完毕。
# 时间复杂度:
- 最坏:(因为一个点可能影响所有已有区域)
- 随机化插入顺序可达期望 (Clarkson & Shor)
# 三、Sweep Line Algorithm(Fortune’s Algorithm)
# 思路:
- 用一条从左往右的扫描线 “扫” 过整个点集。
- 所有 “事件” 点按 坐标排序,包括:
- 点事件(添加新的 site)
- 圆事件(删除某段边,形成 Voronoi 顶点)
- 用 “海滩线”(beach line)维护当前状态:
- 是一条由抛物线拼接而成的曲线
- 每个点产生一段抛物线弧,表示其当前影响范围
- 对每个事件更新结构,最终得到 Voronoi 图。
# 数据结构:
- 优先队列存事件点
- 平衡树维护海滩线结构
# 时间复杂度:
- 总事件数:
- 每次事件处理
- 总体复杂度:
# 四、Divide and Conquer(分治法)
# 思路:
- 将点集按 坐标排序,划分为左右两半。
- 分别递归构造左、右半平面的 Voronoi 图。
- 合并两个 Voronoi 图:
- 找出分界线(也称合并链、merging chain)
- 沿该分界线逐步连接两个子图
- 删除被另一半覆盖的部分结构
# 合并技巧:
- 利用中垂线、最小外接圆、点的相对位置判断结构连接
- 分界线呈 y 单调性,方便构造
# 时间复杂度:
- 每次划分 ,递归深度
- 合并线构造
- 总体复杂度:
# 五、Lifting Method(3D 提升法)
# 思路:
- 将每个平面点 映射到三维空间:
- ,映射到抛物面上
- 构造这组点在三维空间中的 上凸包
- 将上凸包投影回 平面,得到 Delaunay Triangulation
- 再通过对偶关系构造 Voronoi 图
# 优势:
- 可用于高维空间问题
- 和 Delaunay Triangulation 紧密相关
# 时间复杂度:
- 和三维凸包一样:
# 六、小结对比
方法 | 是否容易实现 | 是否高效 | 适合说明 |
---|---|---|---|
增量式 | ✅ 容易入门 | ❌ 较慢 | 教学用途 |
扫描线法 | ❌ 实现复杂 | ✅ 快速 | 工业级构造 |
分治法 | ✅ 实现清晰 | ✅ 快速 | 理论分析 |
提升法 | ❌ 几何较难 | ✅ 快速 | 与 Delaunay 联动 |
# 七、拓展阅读
- Computational Geometry: Algorithms and Applications by de Berg et al.
- Fortune's original paper (1987): A Sweepline Algorithm for Voronoi Diagrams
- Clarkson & Shor (1989): Randomized Incremental Algorithms and Probabilistic Analysis
# Delaunay Triangulation 基础
# 🔺 一、Delaunay Triangulation 是什么?
# 📌 定义:
Delaunay 三角剖分是这样一种三角化方法:
对一组点进行三角剖分,使得任何一个三角形的外接圆中都不包含其它点。
这个条件叫做:
空圆性质(Empty Circle Property)
# 🎯 二、为什么要用 Delaunay?
Delaunay Triangulation 相比于任意三角剖分,有很多好处,尤其是:
# ✅ 角度最优化(Angle Optimality)
它 最大化最小角,也就是说:
避免生成 “又细又瘦” 的长三角形(sliver triangle)
更接近等边三角形,利于数值稳定性与网格质量
这在图形学、有限元分析、地形建模中非常重要。
# ⚖️ 三、Legal Triangulation 与 Delaunay 的等价
你图中写的这句非常关键:
合法三角剖分 ⇔ Delaunay triangulation
这个意思是:
如果一个三角剖分中所有的四边形都满足 “对角线合法”(对角线切换后使得外接圆更空)
那这个三角剖分就是 Delaunay 的
这个 “对角线切换” 叫 edge flipping,是很多 Delaunay 构造算法的核心操作。
# 四、定理
对任意一个点集 的三角剖分,若点数为 ,凸包上的点数为 ,则:
- 三角形数
- 边数
# ✏️ 证明思路:
设三角剖分为 ,记:
- 顶点数:
- 三角形数:
- 面数:( 个三角形 + 外部面)
- 边数:E = \dfrac{3m + k}
- 表示所有三角形的边数(重复计算)
- 外边(即凸包边)只算一次,共 条
- k 为顶点个数,我们知道顶点个数相当于一个多边形外部边的个数,而 相当于 把所有内部三角形公用边算了两次加上所有的外部边一次,所以 就相当于把内外部的边都算了两次
带入欧拉公式(平面图):
即:
整理得:
再带回边数公式:
# 五、Angle Vector 与角度最优三角剖分
Goal: 生成一个三角剖分,使得其最小角最大化。
- 一个三角剖分若有 个三角形,则一共有 个内角
- 将所有内角按升序排列,定义角度向量:
- 若两个三角剖分 与 的角度向量满足:
则表示 比 更优。
- 如果对所有三角剖分 都有 ,那么 是一个角度最优三角剖分。
例子:
则 ,因为第 5 个角更大。
# 六、Legal edges
# 6.1 三角翻转
这一部分可以简单理解为一个四边形通过对角线分成两个三角形,可以进行旋转这个对角线以获得不同的三角形组合,并从中挑选最小角最大的组合。而如果一条边所构造的三角形的最小角小于翻转之后,那么这条边就是违法的。
而需要注意的是,这一部分并不是看翻转后的每一个三角形的最小角,而是看翻转后两个三角形六个角中最小的一个。
而关于非法与合法的对角线还有以下两个结论
# ✅ 结论 1:
如果四个点 p_i、p_j、p_k、p_l 构成一个凸四边形,
并且它们不共圆,
那么在两条对角线(p_i p_j 和 p_k p_l)中,必有一条是非法边。
换句话说:
对于这种四边形结构,它们的两种三角剖分方式(flip 前后的两种)不可能都是合法的
要么 p_i p_j 是非法边,要么 p_k p_l 是非法边,不会同时合法
这其实说明了:总有一种划分方式会让角度更大,更优
# ✅ 结论 2(重点):
如果四边形用对角线 p_i p_j 来三角剖分,
那么这条边 是非法的 ⇔ 点 p_l 落在三角形 p_i p_j p_k 的外接圆内
这个判据非常重要,叫做:
# 🎯 空圆判据(Delaunay condition)
一个三角形的三点构成的外接圆中,如果第四个点在圆内,那当前边就是非法边!
也可以反过来说:
只有当所有三角形的外接圆都不包含其它点时,三角剖分才是 Delaunay 的
# Voronoi 与 Delaunay Triangulation
# Voronoi 与 Delaunay Triangulation 的一些关系
# 1. Voronoi 顶点 与 最大空圆的关系
一个点 是 Voronoi 图 Vor () 的顶点,当且仅当:
存在一个最大空圆,其圆心为
这个圆的边界上恰好有 3 个输入点(, , )
且圆内部没有包含任何其他点
因此,Voronoi 顶点实际上就是这三个点外接圆的圆心。 这也是 Voronoi 和 Delaunay 的一个对偶:
- Voronoi 顶点 ⇔ Delaunay 三角形的外心
# 2. Delaunay 三角形 ⇔ 外接圆为空
三点 , , 构成一个 Delaunay 三角形,当且仅当:
- 它们的外接圆中不包含其他点(即空圆)
这个性质被称为:
空圆判据(Empty Circle Criterion)
也就是说,一个三角形如果能成为 Delaunay 三角形,它的圆中除了这三点不能有其他点。
# 3. Delaunay 边 ⇔ Voronoi cell 相邻
边 是 Delaunay 图中的一条边,当且仅当:
# 方式一:通过 Voronoi 二分线
存在一个 Voronoi 图中的点 ,在 和 的二分线上
并且这个点到其他所有点的距离都更远(即最大空圆只接触这两点)
那么 cell () 与 cell () 相邻,说明这两个点之间有 Delaunay 边
# 方式二:通过空圆盘判据
存在一个圆(disk),其边界上有 和
且这个圆内部不包含任何其它点
那么 是一条合法的 Delaunay 边
# 图像理解补充:
图 1 显示了 Voronoi 顶点作为三个 Voronoi cell 的交点,对应 Delaunay 外心
图 2 强调了三角形外接圆中不能有额外点的 Delaunay 三角形
图 3 展示了连接两个点的 Delaunay 边,其对应的 Voronoi edge 和空圆验证条件
这些性质是理解 Delaunay 与 Voronoi 之间几何对偶的关键基础。
# 定理:Delaunay Triangulation 一定是平面图(Planar)
# 目标:
证明 Delaunay 图 Del (P) 中的边不会相交
# ✳️ 证明方法:反证法(Proof by contradiction)
# 假设:存在两条 Delaunay 边相交
设两条相交的边为:
# 步骤 1:构造以 为边界的空圆
- 存在空圆 , 和 在圆上
- 设圆心为 ,构造三角形
根据 Voronoi 性质:
- 在 Vor () 中
- 在 Vor () 中
结论: 必须在 外部,否则违反空圆判据
# 步骤 2:构造以 为边界的空圆
- 存在空圆 , 和 在圆上,设圆心为 r_
- 构造三角形
考虑两种情况:
# 🔹 Case 1: 和 不与 相交
- 此时三角形 与 没有交集
- 由于 与 是相交的 ⇒ 或 必定落在 内部
- 矛盾: 是空圆,不能包含其他点
🟥 矛盾!
# 🔹 Case 2: 或 与 相交
- 比如 穿过 t_
- 那么 落入 Vor (), 也在 Vor ()
- 说明 Vor () 被两个非相邻边交叉穿过
- 与 Voronoi 图结构矛盾(边不能交叉)
🟥 矛盾!
# ✅ 最终结论:
无论哪种情况,假设边交叉都会导致矛盾
所以 Delaunay Triangulation 中边不能交叉 ⇒ 一定是平面图(planar)