# Voronoi Diagram 基础讲解

# 什么是 Voronoi Diagram?

给定一个点集 P={p1,p2,,pn}P = \{p_1, p_2, \dots, p_n\},Voronoi 图是将平面划分为 nn 个区域(称为 Voronoi Cells),每个区域对应一个点 pip_i,使得该区域中任意一点 qq 满足:

dist(q,pi)<dist(q,pj)ji\text{dist}(q, p_i) < \text{dist}(q, p_j) \quad \forall j \neq i

通俗来说,想象你在一个城市里有很多咖啡店,Voronoi 图的作用就是把整个城市划分成若干区域,每个区域内的所有人,走路距离都最接近某一家咖啡店。换句话说,它告诉你「谁最靠近谁」。


# Voronoi Diagram 的基本构成

  • Voronoi Cell:每个点 pip_i 的最近邻域。
  • Voronoi Edge:两个 Voronoi cell 的公共边,即两个点的中垂线的一部分。
  • Voronoi Vertex:三个或更多 Voronoi cell 的交点,等距于对应的点。

# 图示结构:

1
2
3
4
5
6
7
8
      Voronoi Vertex

/|\
/ | \
/ | \
Cell A / | \ Cell B
-----⬤-----
Voronoi Edge


# 基本性质

  1. 连通性:Voronoi 图是连通图。
  2. 边类型:Voronoi Edge 是线段或射线(半无限长),除非所有点共线。
  3. 复杂度
    • Voronoi 顶点数:最多 2n52n - 5
    • Voronoi 边数:最多 3n63n - 6
    • 结论:总复杂度是线性的 O(n)O(n)

# 空圆性质(Empty Circle Property)

# Voronoi 顶点的判定:

一个点 qq 是 Voronoi 顶点 ⟺ 存在一个最大空圆 CP(q)C_P(q),其边界上恰好有三个点 p1,p2,p3Pp_1, p_2, p_3 \in P,且圆内部不包含其它点。

# Voronoi 边的判定:

两点 p1,p2p_1, p_2 之间存在 Voronoi 边 ⟺ 在它们的中垂线上存在点 qq,其最大空圆仅以 p1,p2p_1, p_2 为边界点。


# 应用举例

  • 疫情分析(如 John Snow 的霍乱图)
  • 最近邻搜索(NN、kNN)
  • 地理信息系统(GIS)
  • 图像处理与分割
  • 网络规划(如通信塔覆盖区域)
  • 机器学习中的聚类(如 K-means)

# Voronoi 图复杂度的欧拉公式证明

我们希望证明:对于 n>2n > 2 个点的 Voronoi 图 V(P)V(P),其复杂度是线性的:

  • 顶点数 2n5\leq 2n - 5
  • 边数 3n6\leq 3n - 6

# 📐 使用欧拉公式

欧拉公式是平面图中的基本定理:

VE+F=2V - E + F = 2

其中:

  • VV 是顶点数
  • EE 是边数
  • FF 是面数(Voronoi cell 数量,即原始点数 nn

# 🔧 添加虚拟点使图封闭

由于 Voronoi 图的某些边是无穷延伸的半线,不能直接套用欧拉公式。为了解决这个问题,我们:

  • 添加一个虚拟点 vv
  • 将所有半线连到 vv,使图成为封闭图

这样我们有一个新的图,满足欧拉公式:

(V+1)E+n=2(记作 *)(V + 1) - E + n = 2 \quad \text{(记作 *)}


# 🔁 顶点度数下界

Voronoi 图中的每个顶点(包括新增的 vv)至少有 度数为 3,因为:

  • 一个 Voronoi 顶点是三个 Voronoi cell 的交点
  • 所以它至少连接三条边

因此:

  • 所有顶点度数之和 3(V+1)\geq 3(V + 1)
  • 而总度数也等于 2E2E

所以:

2E3(V+1)V23E12E \geq 3(V + 1) \Rightarrow V \leq \frac{2}{3}E - 1


# 🔚 代入欧拉公式

将上式代入公式 (*):

(23E1+1)E+n=223EE+n=213E=2nE=3n6\left(\frac{2}{3}E - 1 + 1\right) - E + n = 2 \\ \Rightarrow \frac{2}{3}E - E + n = 2 \\ \Rightarrow -\frac{1}{3}E = 2 - n \\ \Rightarrow E = 3n - 6

再代入 V23E1V \leq \frac{2}{3}E - 1 得:

V23(3n6)1=2n5V \leq \frac{2}{3}(3n - 6) - 1 = 2n - 5


# ✅ 结论

  • 边数 E3n6E \leq 3n - 6
  • 顶点数 V2n5V \leq 2n - 5
  • Voronoi 图总结构复杂度为 O(n)O(n)(线性)

# Voronoi Diagram 的计算方法详解

Voronoi 图的计算,目标是将一组平面点划分成最近邻区域。虽然定义简单,但构造算法非常讲究效率和几何处理的技巧。


# 一、常见算法概览

算法时间复杂度核心思想
增量式构造(Incremental)最坏 O(n2)O(n^2),随机化期望 O(nlogn)O(n \log n)一个点一个点插入,逐步更新结构
扫描线法(Sweep Line / Fortune’s Algorithm)O(nlogn)O(n \log n)用一条从左往右移动的 “海滩线” 维护结构
分治法(Divide and Conquer)O(nlogn)O(n \log n)分别处理左右子集,合并时找出分界线
提升法(Lifting / 3D Convex Hull)O(nlogn)O(n \log n)把二维问题变为三维凸包问题再投影回二维

# 二、Incremental Algorithm(增量式)

# 思路:

  1. 初始 Voronoi 图为空或为第一个点占据全平面。
  2. 逐个插入点 pip_i,在当前结构中找到属于 pip_i 的区域。
  3. 更新 Voronoi 图:以 pip_i 为中心构造新的边和顶点,修剪旧区域。
  4. 不断重复,直到所有点都插入完毕。

# 时间复杂度:

  • 最坏:O(n2)O(n^2)(因为一个点可能影响所有已有区域)
  • 随机化插入顺序可达期望 O(nlogn)O(n \log n)(Clarkson & Shor)

# 三、Sweep Line Algorithm(Fortune’s Algorithm)

# 思路:

  1. 用一条从左往右的扫描线 “扫” 过整个点集。
  2. 所有 “事件” 点按 xx 坐标排序,包括:
    • 点事件(添加新的 site)
    • 圆事件(删除某段边,形成 Voronoi 顶点)
  3. 用 “海滩线”(beach line)维护当前状态:
    • 是一条由抛物线拼接而成的曲线
    • 每个点产生一段抛物线弧,表示其当前影响范围
  4. 对每个事件更新结构,最终得到 Voronoi 图。

# 数据结构:

  • 优先队列存事件点
  • 平衡树维护海滩线结构

# 时间复杂度:

  • 总事件数:O(n)O(n)
  • 每次事件处理 O(logn)O(\log n)
  • 总体复杂度:O(nlogn)O(n \log n)

# 四、Divide and Conquer(分治法)

# 思路:

  1. 将点集按 xx 坐标排序,划分为左右两半。
  2. 分别递归构造左、右半平面的 Voronoi 图。
  3. 合并两个 Voronoi 图:
    • 找出分界线(也称合并链、merging chain)
    • 沿该分界线逐步连接两个子图
    • 删除被另一半覆盖的部分结构

# 合并技巧:

  • 利用中垂线、最小外接圆、点的相对位置判断结构连接
  • 分界线呈 y 单调性,方便构造

# 时间复杂度:

  • 每次划分 O(n)O(n),递归深度 logn\log n
  • 合并线构造 O(n)O(n)
  • 总体复杂度:O(nlogn)O(n \log n)

# 五、Lifting Method(3D 提升法)

# 思路:

  1. 将每个平面点 p=(x,y)p = (x, y) 映射到三维空间:
    • λ(p)=(x,y,x2+y2)\lambda(p) = (x, y, x^2 + y^2),映射到抛物面上
  2. 构造这组点在三维空间中的 上凸包
  3. 将上凸包投影回 xyxy 平面,得到 Delaunay Triangulation
  4. 再通过对偶关系构造 Voronoi 图

# 优势:

  • 可用于高维空间问题
  • 和 Delaunay Triangulation 紧密相关

# 时间复杂度:

  • 和三维凸包一样:O(nlogn)O(n \log n)

# 六、小结对比

方法是否容易实现是否高效适合说明
增量式✅ 容易入门❌ 较慢教学用途
扫描线法❌ 实现复杂✅ 快速工业级构造
分治法✅ 实现清晰✅ 快速理论分析
提升法❌ 几何较难✅ 快速与 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)

    • 更接近等边三角形,利于数值稳定性与网格质量

这在图形学、有限元分析、地形建模中非常重要。


你图中写的这句非常关键:

合法三角剖分 ⇔ Delaunay triangulation

这个意思是:

  • 如果一个三角剖分中所有的四边形都满足 “对角线合法”(对角线切换后使得外接圆更空)

  • 那这个三角剖分就是 Delaunay 的

这个 “对角线切换” 叫 edge flipping,是很多 Delaunay 构造算法的核心操作。

# 四、定理

对任意一个点集 PP 的三角剖分,若点数为 nn,凸包上的点数为 kk,则:

  • 三角形数 =2n2k= 2n - 2 - k
  • 边数 =3n3k= 3n - 3 - k

# ✏️ 证明思路:

设三角剖分为 TT,记:

  • 顶点数:V=nV = n
  • 三角形数:mm
  • 面数:F=m+1F = m + 1mm 个三角形 + 外部面)
  • 边数:E = \dfrac{3m + k}
    • 3m3m 表示所有三角形的边数(重复计算)
    • 外边(即凸包边)只算一次,共 kk
    • k 为顶点个数,我们知道顶点个数相当于一个多边形外部边的个数,而3m3m 相当于 把所有内部三角形公用边算了两次加上所有的外部边一次,所以3m+k3m+k 就相当于把内外部的边都算了两次
      带入欧拉公式(平面图):

VE+F=2V - E + F = 2

即:

n3m+k2+(m+1)=2n - \dfrac{3m + k}{2} + (m + 1) = 2

整理得:

m=2n2km = 2n - 2 - k

再带回边数公式:

E=3m+k2=3(2n2k)+k2=3n3kE = \dfrac{3m + k}{2} = \dfrac{3(2n - 2 - k) + k}{2} = 3n - 3 - k

# 五、Angle Vector 与角度最优三角剖分

Goal: 生成一个三角剖分,使得其最小角最大化

  • 一个三角剖分若有 mm 个三角形,则一共有 3m3m 个内角
  • 将所有内角按升序排列,定义角度向量:

A(T)=(α1,α2,α3,,α3m)A(T) = (\alpha_1, \alpha_2, \alpha_3, \ldots, \alpha_{3m})

  • 若两个三角剖分 TTTT' 的角度向量满足:

A(T)>A(T)i使得αj=αjfor allj<i,αi>αiA(T) > A(T') \iff \exists i \text{ 使得 } \alpha_j = \alpha'_j \text{ for all } j < i, \text{ 且 } \alpha_i > \alpha'_i

则表示 TTTT' 更优。

  • 如果对所有三角剖分 TT' 都有 A(T)A(T)A(T) \geq A(T'),那么 TT 是一个角度最优三角剖分

例子

  • A(T)=(12,14,14,15,21,22,)A(T) = (12, 14, 14, 15, 21, 22, \ldots)
  • A(T)=(12,14,14,15,19,22,)A(T') = (12, 14, 14, 15, 19, 22, \ldots)
    T>TT > T',因为第 5 个角更大。

# 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 顶点 与 最大空圆的关系

一个点 qq 是 Voronoi 图 Vor (PP) 的顶点,当且仅当:

  • 存在一个最大空圆,其圆心为 qq

  • 这个圆的边界上恰好有 3 个输入点pip_i, pjp_j, pkp_k

  • 且圆内部没有包含任何其他点

因此,Voronoi 顶点实际上就是这三个点外接圆的圆心。 这也是 Voronoi 和 Delaunay 的一个对偶:

  • Voronoi 顶点 ⇔ Delaunay 三角形的外心

# 2. Delaunay 三角形 ⇔ 外接圆为空

三点 pip_i, pjp_j, pkp_k 构成一个 Delaunay 三角形,当且仅当:

  • 它们的外接圆中不包含其他点(即空圆)

这个性质被称为:

空圆判据(Empty Circle Criterion)

也就是说,一个三角形如果能成为 Delaunay 三角形,它的圆中除了这三点不能有其他点。


# 3. Delaunay 边 ⇔ Voronoi cell 相邻

(pi,pj)(p_i, p_j) 是 Delaunay 图中的一条边,当且仅当:

# 方式一:通过 Voronoi 二分线

  • 存在一个 Voronoi 图中的点 qq,在 pip_ipjp_j 的二分线上

  • 并且这个点到其他所有点的距离都更远(即最大空圆只接触这两点)

  • 那么 cell (pip_i) 与 cell (pjp_j) 相邻,说明这两个点之间有 Delaunay 边

# 方式二:通过空圆盘判据

  • 存在一个圆(disk),其边界上有 pip_ipjp_j

  • 且这个圆内部不包含任何其它点

  • 那么 (pi,pj)(p_i, p_j) 是一条合法的 Delaunay 边


# 图像理解补充:

  • 图 1 显示了 Voronoi 顶点作为三个 Voronoi cell 的交点,对应 Delaunay 外心

  • 图 2 强调了三角形外接圆中不能有额外点的 Delaunay 三角形

  • 图 3 展示了连接两个点的 Delaunay 边,其对应的 Voronoi edge 和空圆验证条件

这些性质是理解 Delaunay 与 Voronoi 之间几何对偶的关键基础。

# 定理:Delaunay Triangulation 一定是平面图(Planar)

# 目标:

证明 Delaunay 图 Del (P) 中的边不会相交


# ✳️ 证明方法:反证法(Proof by contradiction)

# 假设:存在两条 Delaunay 边相交

设两条相交的边为:

  • (pi,pj)(p_i, p_j)
  • (pk,pl)(p_k, p_l)

# 步骤 1:构造以 (pi,pj)(p_i, p_j) 为边界的空圆

  • 存在空圆 CijC_{ij}pip_ipjp_j 在圆上
  • 设圆心为 rijr_{ij},构造三角形 tij=(rij,pi,pj)t_{ij} = \triangle(r_{ij}, p_i, p_j)

根据 Voronoi 性质:

  • rijpi\overline{r_{ij}p_i} 在 Vor (pip_i) 中
  • rijpj\overline{r_{ij}p_j} 在 Vor (pjp_j) 中

结论:(pk,pl)(p_k, p_l) 必须在 CijC_{ij} 外部,否则违反空圆判据


# 步骤 2:构造以 (pk,pl)(p_k, p_l) 为边界的空圆

  • 存在空圆 CklC_{kl}pkp_kplp_l 在圆上,设圆心为 r_
  • 构造三角形 tkl=(rkl,pk,pl)t_{kl} = \triangle(r_{kl}, p_k, p_l)

考虑两种情况:

# 🔹 Case 1:rklpk\overline{r_{kl}p_k}rklpl\overline{r_{kl}p_l} 不与 tijt_{ij} 相交

  • 此时三角形 tklt_{kl}tijt_{ij} 没有交集
  • 由于 (pi,pj)(p_i, p_j)(pk,pl)(p_k, p_l) 是相交的 ⇒ pip_ipjp_j 必定落在 CklC_{kl} 内部
  • 矛盾:CklC_{kl} 是空圆,不能包含其他点

🟥 矛盾!


# 🔹 Case 2:rklpk\overline{r_{kl}p_k}rklpl\overline{r_{kl}p_l}tijt_{ij} 相交

  • 比如 rklpk\overline{r_{kl}p_k} 穿过 t_
  • 那么 rklpk\overline{r_{kl}p_k} 落入 Vor (pjp_j),rijpj\overline{r_{ij}p_j} 也在 Vor (pjp_j)
  • 说明 Vor (pjp_j) 被两个非相邻边交叉穿过
  • 与 Voronoi 图结构矛盾(边不能交叉)

🟥 矛盾!


# ✅ 最终结论:

无论哪种情况,假设边交叉都会导致矛盾

所以 Delaunay Triangulation 中边不能交叉 ⇒ 一定是平面图(planar)