凸包算法 (Convex Hull)
给定平面上的一组点,能够包含所有这些点的最小凸多边形称为凸包(Convex Hull)。在计算几何中,凸包算法是许多复杂问题的预处理基石。
1. 形式化定义与拓扑性质
1.1 Andrew 算法(单调链法)的单调性证明
Andrew 算法通过将凸包分解为**上凸壳(Upper Hull)和下凸壳(Lower Hull)**进行构建。
证明:拓扑单调性与正确性
- 全序单调性:首先按 坐标升序( 相同时按 升序)对点集 排序。排序后的序列 确保了 和 必为凸包上的顶点(极点)。
- 局部凸性维持:在构建下凸壳时,维护一个栈 。对于新点 ,若 ,说明 相对于 和 构成的链发生了“右转”或共线。
- 代数含义:叉积 意味着 落在向量 的右侧。
- 单调性:由于 ,弹出 后连接 与 必然会扩大下方覆盖区域且保持下凸性。
- 收敛性:扫描完成后,下凸壳从 单调增加至 (按 轴正向),上凸壳从 单调减少回 (按 轴负向)。两链合围形成的区域包含了 的所有点,且由于每一步都强制“左转”(Left-turn),结果必为凸集。
2. 拓扑一致性验证 (Topological Consistency)
在构建凸包时,退化情况可能破坏拓扑结构:
3. 教材级核心代码实现 (C++)
4. 经典推导与练习库 (Exercises)
例题 1:动态凸包判定 - 二分加速证明
题目描述:给定一个逆时针序凸多边形,判断点 是否在内部。 推导: 对于凸多边形 ,取 为原点。点 在多边形内当且仅当:
- 落在角 之间。
- 找到 使得 落在角 内。
- 在有向边 的左侧。 由于 随 单调递增,步骤 2 可通过二分查找在 完成。
Check Solution
练习 1:闵可夫斯基和 (Minkowski Sum)
题目描述:计算两个凸多边形 的向量和 。 定理:两个凸多边形的闵可夫斯基和仍为凸多边形,且其边集为 和 的边集按极角排序后的合并。 应用:判断两个凸多边形是否相交。。
Check Solution
练习 2:动态凸包维护 (Online Convex Hull)
题目描述:支持动态插入点并实时查询凸包面积。
思路:使用 std::set 按极角或坐标维护凸包顶点。插入点时,通过 lower_bound 找到邻居,利用叉积判断是否需要弹出受影响的旧顶点。
Check Solution
提示:维护上凸壳与下凸壳的两个 std::set<Point>。插入点 时,若 已在壳内则跳过;否则插入并向两侧通过 while 循环删除非凸点。
🎯 模块导航
- 旋转卡壳 (Rotating Calipers) - 凸包直径与最小外接矩形。
- 半平面交 (Half-plane Intersection) - 线性约束求解证明。
- 计算几何基础 - 精度控制与向量原语。