Skip to content

算法Algorithm

单调多边形的线性栈剖分

Linear-time monotone polygon triangulation

合并两条单调边界链后,用未处理边界的凹链栈在线性时间输出合法对角线。

形式陈述 ​

如果一个简单多边形已经单调,为什么还要像耳切一样反复搜索整条边界?设输入为逆时针 y-单调多边形,有唯一最高、最低点。两条从上到下的边界链已经有序,把它们线性归并,得到 u1,…,un。内部点标为左链或右链,最高、最低点同时属于两链。

维护一个栈,初始压入 u1,u2。依次处理 uj,3≤j<n:

  • 若 uj 与栈顶在不同链,从栈顶向下输出以 uj 为第三顶点的三角形,直到栈只剩一个点;随后把旧栈顶与 uj 作为新的两点栈
  • 若在同一链,先弹出旧栈顶 b。令当前栈顶为 c,只要对角线 ujc 位于当前未剖区域内,就输出三角形 ujbc,再令 b=c 并继续弹栈。停止后把最后的 b 和 uj 压回

同链可见性可以由一个叉积判断。两链从最高点走向最低点,若 uj 在左链,合法弹栈条件为

orient(uj,b,c)<0;

右链则为大于零。这里的顺序是“新点、刚弹出的点、下一栈顶”,换顺序必须同时换符号。最后用最低点 un 与栈中连续两点逐片输出剩余三角形。

直觉

扫过的顶点不全都需要留着。已经围成三角形的部分可以立即封存;尚未剖分的上方区域,只留下一个由一条边和一段凹链围成的口袋。栈保存这段凹链,从底到顶高度下降。

新点来到另一条链时,能从另一侧看见整段栈链,所以可以一口气剖掉这个口袋。新点仍在同一链时,只有栈顶附近的一段变得可见;顺着凸转向弹栈,遇到第一个遮挡方向便停。条件不是“边长比较”或“顶点高度更低”,而是当前未处理区域的几何形状。

这给出归纳不变量:已输出三角形内部不交;未处理区域仍由未扫描边界和栈上的凹链组成;每条新对角线位于这个区域中。异链清空和同链逐个弹出都保持它,所以无需每次重新对全部边做线段相交检测。

栈维护未剖分边界
例子与边界

取单调分块页中第三个面,循环边界为

(5,7,8,9,0,1),

仍使用其坐标及高度 h=y+x/1000。从高到低的合并顺序是

8,9,7,5,1,0.

初始栈为 [8,9]。顶点 7 来自另一链,输出 (7,8,9),更新栈为 [9,7]。顶点 5 与 7 同链,并且

orient(v5,v7,v9)=4>0.

它位于该面的右链,所以这个符号允许弹出,输出 (5,7,9),栈变为 [9,5]。

接着处理 v1,当前叉积不满足右链弹出条件,不能强行连接到 v9。栈变为 [9,5,1]。最后最低点 v0 依次生成 (0,1,5) 和 (0,5,9)。六个顶点得到四个三角形,正好是 n−2;新对角线为 7−!9,5−!9,0−!5。

这个历史同时包含异链清空、同链成功弹栈和同链停止三种动作。若把右链判断误写为小于零,第二步就会留下本应剖掉的口袋;若忽略链标签,只凭同一个正负号处理两侧,镜像输入会立即失败。

图中的“栈”与单调栈题里的值序列不同。这里的相邻项保存的是边界的几何凹链,并没有要求 x 坐标或边长单调。普通数组极值的支配关系不能代替此处的可见性证明。

推论与应用

每个输入顶点只在首次扫描时加入;用于连接下一轮的旧栈顶可能被保留一次。每次非恒定工作都输出三角形或永久弹掉一个栈记录,总压栈、弹栈次数都是 O(n),输出本身也有 n−2 项。因此两链已排序时,执行时间和空间都为 O(n)。两条链各自有序,只需归并,无需重新调用 O(nlog⁡n) 排序。

本单元的独立核验程序为简化事件表使用通用排序;其所展示的栈阶段仍逐次记录压栈、弹栈,但整份参考程序的时间包含排序成本。算法的线性实现应直接归并输入边界两链,而不是用参考代码的排序步骤冒充线性。

平局先用一致的符号剪切消除,方向谓词仍取原坐标。若有共线边界点,不能输出零面积三角形来凑数;可规范化连续共线点并保留映射,或采用支持边界细分的完整退化版本。非单调多边形必须先划分,否则“另一链能看见整个栈”的关键性质没有依据。

与耳切相比,这里的速度来自输入已经提供两条单调链这一额外结构。它既不优化最小角,也不保证 Delaunay 空圆性。用于路径查询或有限元组装时,剖分合法性和三角形质量仍是两份不同检查。

参考资料
  • Mark de Berg 等,Computational Geometry: Algorithms and Applications,第 3 版,2008,§3.3,TriangulateMonotonePolygon 及凹链不变量,印刷 pp.55–59。课程原书
  • Dave Mount,Polygon Triangulation,2026,pp.3–6,单调剖分的同链/异链执行与线性计数。
关系图谱9 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系