旋转卡壳--凸包的直径
2011-09-23 12:55
183 查看
凸包的直径
例题:
poj 2187 直接求直径OK凸包的直径
多边形的直径被定义为多边形上任意两点间的最大距离的值。 在多边形上,决定直径的点可能不止一对。 事实上,如果一个多边形含有n个顶点,那么就最多有 n 对“直径点对”在。上图所示的是一个简单的多边形直径的实例。 直径点对在图中是被平行的切线(用红色表示)穿过的黑点. 直径是用淡蓝色高亮表示的。
很明显, 确定凸多边形 P 直径的点对不可能在多边形 P 内部。 所以搜索应该在边界上进行。 事实上, 由于直径是多边形的平行切线的最远距离, 所以我们只需要查询对踵点。 Shamos (1978) 提供了一个 简单的 时间复杂度为O(n) 的计算凸包对踵点对的算法。这个算法是通过遍历这些点的列表, 得到最大距离即直径,然后输出这个点对。 下面是Shamos 算法的伪代码,1985年在
Preparata 和 Shamos 文章中进行发表。
输入是一个多边形 P={p1,...,pn}
begin p0:=pn; q:=NEXT[p]; while (Area(p,NEXT[p],NEXT[q]) > Area(p,NEXT[p],q)) do q:=NEXT[q]; q0:=q; while (q != p0) do begin p:=NEXT[p]; Print(p,q); while (Area(p,NEXT[p],NEXT[q]) > Area(p,NEXT[p],q) do begin q:=NEXT[q]; if ((p,q) != (q0,p0)) then Print(p,q) else return end; if (Area(p,NEXT[p],NEXT[q]) = Area(p,NEXT[p],q)) then if ((p,q) != (q0,p0)) then Print(p,NEXT[q]) else Print(NEXT[p],q) end end.
注意 Print(p,q) 表示将 (p,q) 作为一个对踵点对输出, Area(p,q,r) 表示三角形 pqr 的有向面积。
虽然直觉看这个过程与常规旋转卡壳算法不同, 但从本质上看是相同的, 并且避免了任何角度的计算。
下面试是一个比较直观的算法:
1、计算出多边形 y 方向上的端点。 设为 ymin 和 ymax 。
2、通过 ymin 和 ymax 构造两条水平切线。 由于他们已经是一对对踵点, 计算他们之间的距离并维护为一个当前最大值。
3、同时旋转两条线直到其中一条与多边形的一条边重合。
4、一对新的对踵点对此时产生。 计算新的距离, 并和当前最大值比较, 大于当前最大值则更新。
5、重复步骤3和步骤4的过程直到再次产生对踵点对 (ymin,ymax) 。
6、输出确定最大直径的对踵点对。
虽然上述的过程(给出的伪代码)变得非常有用, 但是我们仍可以从对踵点对中得到其他的信息, 如多边形的宽度 。
相关文章推荐
- poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方
- POJ 2187 Beauty Contest(旋转卡壳求点凸包直径)
- 旋转卡壳找凸包直径解poj2187Beauty Contest
- 旋转卡壳--求凸包最大直径
- POJ2187Beauty Contes【凸包Graham+旋转卡壳求凸包直径+排除共线】
- POJ 2187 求多边形直径(凸包+旋转卡壳)
- 旋转卡壳--求凸包(点集)直径
- POJ 2187 —— 凸包 + 旋转卡壳 求多边形的直径
- 旋转卡壳--求凸包最大直径
- poj 2187 Beauty Contest (凸包: 最远点对,最长直径 , 旋转卡壳法)
- 计算凸包直径—旋转卡壳算法
- 旋转卡壳,凸包直径(正方形,LA 4728)
- UVa 1453 - Squares 旋转卡壳求凸包直径
- poj-2187-凸包-旋转卡壳法求直径
- LA 4728 旋转卡壳算法求凸包的最大直径
- poj 2187 凸包上的直径 - 旋转卡壳
- POJ 2187 旋转卡壳求凸包的直径
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
- UVALive 4728 Squares(旋转卡壳求凸包直径)