旋转卡壳卡卡

关于旋转卡壳的比较详细的介绍,这里有两篇文章(支持原创,拒绝转载)

http://blog.sina.com.cn/s/blog_4afd4f7c010004y4.html

http://www.cppblog.com/staryjy/archive/2010/09/25/101412.html
这两篇适合于不知道旋转卡壳为何物时入门用。

 

另外,这里有关于旋转卡壳详尽的解释与应用说明(包括点集的直径,凸多边形的宽,两凸包的最远距离,两凸包的最近距离等)http://cgm.cs.mcgill.ca/~orm/rotcal.html
不要因为都是英文而不想看,而去看中文版的,大牛的博客都是写给他们自娱自乐然后让一帮小弟膜拜的,仔细看一下原版会有很大帮助。中文版的只在于理解,而不能深刻理解。

然后就是我的旋转卡壳了,poj2187这个题可以直接水过,不用旋转卡壳就可以,toj2847就必须要用卡壳了

 

 

以上就是求点集直径(最远点对)的应用,而下面我们就解决旋转卡壳求两个凸包的最近距离的问题。
1.  Compute the vertex with minimum y coordinate for P (call it yminP) and the vertex with maximum y coordinate for Q (call it ymaxQ).
2. Construct two lines of support LP and LQ for the polygons at yminP and ymaxQ such that the polygons lie to the right of their respective lines of support. Then LP and LQ have opposite direction, and yminP and ymaxQ form an anti-podal pair between the polygons.
3. Compute dist(yminP,ymaxQ) and keep it as the minimum.
4. Rotate the lines clockwise until one of them coincides with an edge of its polygon.
5. If only one line coincides with an edge, then the vertex-edge anti-podal pair distance should be computed along with the new vertex-vertex anti-podal pairA distance. Both distances are compared the current minimum, which is updated if necessary. If both lines of support coincide with edges, then the situation is somewhat more complex. If the edges "overlap", that is if one can construct a line perpendicular to both edges and intersecting both edges (but not at vertices), then the edge-edge distance should be computed. Otherwise the three new vertex-vertex anti-podal pair distances are computed. All distances are compared to the current minimum which is updated if necessary.
6. Repeat steps 4 and 5, until the lines reach (yminP, ymaxQ) again.
7. Output the minimum distance.

这是英文版的最近点对的算法,简单翻译一下:
1、两个凸多边形,记为P和Q,计算出P中y坐标最小的点(记为yminP) ,还有Q中y坐标最大的点(记为ymaxQ);
2、分别过yminP和yminQ做直线,并且使两条直线平行(旋转卡壳的过程中始终保持平行),记为LP和LQ,此时凸多边形分别位于LP和LQ的右边。LP和LQ具有相反的方向,yminP和ymaxQ就构成了一对对踵点(对踵点的概念google一下)
3、计算yminP和ymaxQ的距离,存入最小距离(记为minimum);
4、顺时针旋转直线(两条直线都旋转),直到其中一条直线与多边形的某条边重合。
5、如果此时只有一条直线与多边形的一条边重合,假如说LP和P的某一条边(记为e)重合,那么可能的最近的点就是当前LQ与Q相交的那个顶点到e的最短距离(点到线段的最短距离);如果LP和LQ都与多边形的某条边重合,那么如果有一条直线可以同时相交于这两个边并且垂直于这两条边,那么LP和LQ之间的距离即为可能的最近距离,否则就计算点到线段的距离(这一步可以简化为:两条边分别为p1p2,q1q2,就计算p1到q1q2的最短距离,p2到q1q2的最短距离,q1到p1p2的最短距离,q2到p1p2的最短距离,然后取四个值的最小值),得到最小值以后,更新minimum
6、重复4和5,直到回到初始状态
7、输出最小距离
算法结束;

下面是应用实例:

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值