World Final

God Medal
凸包之间的最短距离 [翻译 by Nicholas]
      给定两个不相交的凸多边形P和Q,我们要找到一对点(p, q),(p属于P, q属于Q),使得他们之间的距离最小。
事实上两个凸包不相交这个假设是十分重要的,因为这样就保证了凸包包含了他内部的点。如果这两个凸包是相交的,那么计算他们之间的距离是没有意义的。但是,这个问题的另一个版本,两个凸包顶点之间的最小距离在这种情况下是有解的。

      回到我们所讨论的问题上,很明显我们凭直觉可以判断凸包之间的距离不可能有他们内部的点决定。类似于最大距离的问题,我们有类似的结论:

       P ,Q两个凸包之间的最小距离由他们之间的anti-podal pair 决定。anti-podal pair between the polygons有如下三种情况:

1、The vertex-vertex case 
2、The vertex-edge case 
3、The edge-edge case

也就是说,凸包之间的距离并不一定要由凸包的顶点决定。下面的三幅图说明的上面列出的三种情况:

  


基于上面的结论,我可以想到一个基于旋转卡壳的算法:
考虑下面的算法,输入是两个顺时针的凸包P, Q

1.     计算凸包P在y轴方向上的最小值记为yminP,和凸包Q在y轴方向上的最大值记为ymaxQ。
2.     建立两条紧贴着yminP, ymaxQ的两条水平的直线LP, LQ。要求他们指向不同的方向。这时候他们就形成了一对anti-podal pair。
3.     计算(yminP,ymaxQ)的距离,并记为minimum.
4.     将两条直线顺时针旋转,直到其中一条遇到凸包的一条边停止。
5.     只要有一条直线遇到了一条边,我们就需要计算新的vertex-vertex anti-podal之间的距离,并同minimum比较,并更新。如果两条直线都分同     一     条     边重合,那么情况就复杂一些了。如果这两条边”重合“,也就是说我们可以画一条垂直于这两条直线的直线并且和凸包上的两个边都相交(不包括在顶点相交),那么我们就需要计算两条直线的距离了。否则的话我们只要计算3个新的顶点到顶点之间的距离。所有的具体都要同minimum比较,并更新minimum 的值。
6.     重复步骤4,5,直到两条直线又回到起始位置为止。
7.     输出最小的距离。

旋转卡壳的方法保证的所有的anti-podal pairs 都被检查了。而且整个的算法有着线性的时间复杂度。因为每个顶点只可能被检查一次。



posted on 2008-08-06 22:39  BLess  阅读(1793)  评论(1编辑  收藏  举报