合并凸包
考虑如下问题: 给定两个凸多边形, 包含他们并的最小凸多边形是怎样的? 答案即合并凸包后得到的凸多边形。合并凸包可以通过一个低效的方式实现: 给定两个多边形的所有顶点, 计算这些点对应的凸包。 更高效的方法是存在的, 他依赖于多边形间的 桥 的查找。 下图描述了这个概念:
两个不相交的凸多边形。 合并后的凸包包含两个多边形中的凸包链(途中蓝色粗实线), 通过多边形间的桥进行连接(途中蓝色虚线)
给定两个不相交的多边形, 在多边形间存在两条桥。 多边形相交时, 拥有和顶点数同样数量的桥, 如下图所示:
两个相交的凸多边形。 合并凸包只包含多边形间的桥(图中虚线所示)。 存在连接八个顶点的八个桥。
合并操作的核心是分治方法。 他同样用于多边形中。 一个获取凸包的十分简单的方法是将点集分为两部分, 分别计算两个较小点集的凸包, 并且将他们合并。 每个集合再次被分割, 直到元素的个数足够小(比如说三个或者更少) 因此凸包就能被很容易获得了。
Toussaint 提出利用旋转卡壳来寻找两个凸多边形间的桥。 这个方法的主要优点在于其利用回溯, 并且多边形可以交叠(其他的算法要求多边形不相交)。 下述结论是他的算法的主要过程:
给定凸多边形 P = { p(1) , ... , p( m) } 和 Q = { q(1) , ... , q( n) },一个点对 ( p( i), q( j)) 形成 P 和 Q 之间的桥当且仅当:
- (p(i), q(j)) 形成一个并踵点对。
- p(i-1), p(i+1), q(j-1), q(j+1) 都位于由 (p(i), q(j)) 组成的线的同一侧。
- 分别计算 P 和 Q 拥有最大 y 坐标的顶点。 如果存在不止一个这样的点, 取 x 坐标最大的。
- 构造这些点的遂平切线, 以多边形处于其右侧为正方向(因此他们指向 x 轴正方向)。
- 同时顺时针旋转两条切线直到其中一条与边相交。 得到一个新的并踵点对 (p(i), q(j)) 。 对于平行边的情况, 得到三个并踵点对。
- 对于所有有效的并踵点对 (p(i), q(j)): 判定 p(i-1), p(i+1), q(j-1), q(j+1) 是否都位于连接点 (p(i), q(j)) 形成的线的同一侧。 如果是, 这个并踵点对就形成了一个桥, 并标记他。
- 重复执行步骤3和步骤4直到切线回到他们原来的位置。
- 所有可能的桥此时都已经确定了。 通过连续连接桥间对应的凸包链来构造合并凸包。
一个凸多边形间的桥实际上确定了另一个有用的概念:多边形间公切线。 同时, 桥也是计算凸多边形交的算法核心。
原文地址:http://cgm.cs.mcgill.ca/~orm/mergech.html
转载请注明出处,谢谢!