POJ 3608 Bridge Across Islands(旋转卡壳求凸多边形最短距离)

标签: 旋转卡壳
679人阅读 评论(2) 收藏 举报
分类:
大意:求解两个凸多边形的最短距离。

分析:依然是旋转卡壳来解决。用一对平行支撑线围绕两个凸多边形来寻找最短的距离。
计算P多边形y最小的端点和Q多边形y最大的端点,即ymin,ymax
通过ymin,ymax构造两条支撑射线LP和LQ,方向相反。两个ymin,ymax的端点的距离作为所求距离的初始值,然后旋转两条支撑线。
当满足有一条平行支撑线和凸多边形的边平行(重合)时,开始相应的判断。
判断的情况:
当有一条平行支撑线和凸多边形的边重合:
(1) 点和线段e的距离最短
(2) 点和新点的距离最短(旧点之前已经判断了)

当两条平行线均和凸多边形的边重合时:
(3) 线段和线段的距离是最短的(一段距离)
(4) 最短距离产生于线段的端点的距离(四段距离)

上面的求解情况转化成 点到点的距离,点到线的距离,线到线的距离(可转化成点到线的距离)



#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const double eps=1e-7,inf=1e99;
const int N=1e4+10;
struct point{
    double x,y;
};
double dis(point a,point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double cross(point p0,point p1,point p2){
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}

double multi(point p0,point p1,point p2){  //点积 p0为角点
    return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}

double getDis(point p0,point p1,point p2){
     if(dis(p0,p1)<eps) return dis(p2,p0);
     if(multi(p0,p1,p2)<-eps) return dis(p2,p0);
     if(multi(p1,p0,p2)<-eps) return dis(p2,p1);
     return fabs(cross(p0,p1,p2)/dis(p0,p1));  //点到线的距离
}

double minDis(point p1,point p2,point p3,point p4){
     return min(min(getDis(p1,p2,p3),getDis(p1,p2,p4)),min(getDis(p3,p4,p1),getDis(p3,p4,p2)));
}

double work(point p[],point q[],int top1,int top2){
    int ymin=0,ymax=0;
    for(int i=0;i<top1;i++){
        if(p[i].y<p[ymin].y) ymin=i;
    }
    for(int i=0;i<top2;i++){
        if(q[i].y>q[ymax].y) ymax=i;
    }
    p[top1]=p[0];
    q[top2]=q[0];
    double t,ans=inf;
    for(int i=0;i<top1;i++){
        while(t=cross(p[ymin],p[ymin+1],q[ymax])-cross(p[ymin],p[ymin+1],q[ymax+1])<-eps) ymax=(ymax+1)%top2;
        if(t>eps) ans=min(ans,getDis(p[ymin],p[ymin+1],q[ymax]));
        else ans=min(ans,minDis(p[ymin],p[ymin+1],q[ymax],q[ymax+1]));
        ymin=(ymin+1)%top1;
    }
    return ans;
}
point p[N],q[N];
int top1,top2;
int main()
{
    //freopen("cin.txt","r",stdin);
    while(cin>>top1>>top2&&(top1+top2)){
        for(int i=0;i<top1;i++){
            scanf("%lf%lf",&p[i].x,&p[i].y);
        };
        for(int i=0;i<top2;i++){
            scanf("%lf%lf",&q[i].x,&q[i].y);
        }
        printf("%.5lf\n",min(work(p,q,top1,top2),work(q,p,top2,top1)));
    }
    return 0;
}


查看评论

高级特效-多边形特效/PS高端辅助/动态人像速成特效 [精品推荐]

-
  • 1970年01月01日 08:00

hdu 2823 The widest road (旋转卡壳求两凸包的最近距离)

The widest road Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...
  • clover_hxy
  • clover_hxy
  • 2017-01-04 17:49:47
  • 363

POJ 3608 旋转卡壳求解凸包间的最短距离

题意给你两个凸包,求解两个凸包间的最短距离。 #include #include #include #include #include using namespace std; ...
  • xuanandting
  • xuanandting
  • 2016-07-26 21:18:21
  • 366

旋转卡壳——凸多边形的宽度

出处:http://blog.csdn.net/acmaker/article/details/3177292 凸多边形的宽度定义为平行切线间的最小距离。 这个定义从宽度这个词中已经略有体现。 虽然...
  • GeiZuoZuoZuo
  • GeiZuoZuoZuo
  • 2013-05-31 11:18:58
  • 1025

poj3608(旋转卡壳求两凸包间的最短距离)

/* translation: 求两个凸包间的最小距离? solution: 旋转卡壳法。 note: * 网上给出的资料都差不多,具体如下: 1. 计算凸包P在y轴方向上的最小值记为ymin...
  • qq_29169749
  • qq_29169749
  • 2017-02-27 22:34:50
  • 88

旋转卡壳---凸多边形间最小距离

给定两个不相连(也就是不相交)的凸多边形 P 和 Q, 目标是找到它们之间的最小距离的点对 (p,q) (p 属于 P 且 q 属于Q)。       事实上, 多边形不相交十分重要, 因为我们所说...
  • zhang20072844
  • zhang20072844
  • 2011-09-27 22:28:07
  • 2127

计算几何之旋转卡壳算法

转载于 http://blog.csdn.net/acmaker/article/details/3188177 一、目录 一些历史: 1978年, M.I. Shamos's...
  • wang_heng199
  • wang_heng199
  • 2017-07-05 18:48:04
  • 1273

计算几何——旋转卡壳

以下所有文章均转载( http://blog.csdn.NET/acmaker/article/details/3176910) 转载请注明出处! 旋转卡壳——翻译说明文档    ...
  • YitongJun
  • YitongJun
  • 2017-02-04 17:31:27
  • 315

POJ3608(旋转卡壳--求两凸包的最近点对距离)

题目:Bridge Across Islands   分析:以下内容来自:http://blog.csdn.net/acmaker/article/details/3178696   考虑如下的算法,...
  • ACdreamers
  • ACdreamers
  • 2013-08-17 15:50:28
  • 3991

<em>旋转卡壳</em>算法讲解

寻找凸多边形直径的一个非常简单的算法, 即根据多边形的一对点<em>距离</em>的最大值来...<em>旋转卡壳</em>--求凸包最大直径 <em>旋转卡壳</em>算法讲解 立即下载 上传者: BlackJack_ ...
  • 2018年04月17日 00:00
    个人资料
    持之以恒
    等级:
    访问量: 37万+
    积分: 9454
    排名: 2423
    我的链接
    最新评论