您的位置:首页 > 其它

计算几何之旋转卡壳初步

2017-01-17 16:09 169 查看
旋转卡壳可以用于求凸包的直径、宽度,两个不相交凸包间的最大距离和最小距离等

这里我们只讲——旋转卡壳求凸包最大直径

1、形象的表示为用一对平行线来卡住凸包上的两个相对的点,然后通过旋转这对平行线能够得到凸包上距离最远的一对点

2、基本思路(转自http://www.cnblogs.com/DreamUp/archive/2010/09/16/1828131.html

(1)逆向思考,如果qa,qb是凸包上最远两点,必然可以分别过qa,qb画出一对平行线。通过旋转这对平行线,我们可以让它和凸包上的一条边重合,如图中蓝色直线,可以注意到,qa是凸包上离p和qb所在直线最远的点。于是我们的思路就是枚举凸包上的所有边,对每一条边找出凸包上离该边最远的顶点,计算这个顶点到该边两个端点的距离,并记录最大的值。直观上这是一个O(n2)的算法,和直接枚举任意两个顶点一样了。但是注意到当我们逆时针枚举边的时候,最远点的变化也是逆时针的,这样就可以不用从头计算最远点,而可以紧接着上一次的最远点继续计算。于是我们得到了O(n)的算法。



(2)模板

int rotating_calipers()
{
int q=1;
int ans=0;
top++;
stack[top]=0;
for(int i=0;i<top;i++)
{
while(Area2(P[stack[i]],P[stack[i+1]],P[stack[q+1]])>Area2(P[stack[i]],P[stack[i+1]],P[stack[q]]))
q=(q+1)%(top);
ans=max(ans , max(Length((P[stack[i]]-P[stack[q]])),Length(P[stack[i+1]]-P[stack[q]])));
//或者ans=max(ans , max(Length((P[stack[i]]-P[stack[q]])),Length(P[stack[i+1]]-P[stack[q+1]])));
}
return ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: