关闭

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

标签: 旋转卡壳
585人阅读 评论(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;
}


0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

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

出处:http://blog.csdn.net/acmaker/article/details/3178696 凸多边形间最小距离 给定两个非连接(比如不相交)的凸多边形 P 和 Q, ...
  • GeiZuoZuoZuo
  • GeiZuoZuoZuo
  • 2013-05-31 11:19
  • 1030

【最小矩形面积覆盖:凸包+旋转卡壳】UVA 10173 Smallest Bounding Rectangle

【最小矩形面积覆盖:凸包+旋转卡壳】UVA 10173 Smallest Bounding Rectangle题目链接:UVA 10173 Smallest Bounding Rectangle题目...
  • u012717411
  • u012717411
  • 2015-08-02 21:50
  • 1222

旋转卡壳——凸多边形最小周长外接矩形

出处:http://blog.csdn.net/acmaker/article/details/3188177 凸多边形最小周长外接矩形 这个问题和最小面积外接矩形相似。 我们的目标是找到...
  • GeiZuoZuoZuo
  • GeiZuoZuoZuo
  • 2013-05-31 11:43
  • 1501

poj 3608 Bridge Across Islands(旋转卡壳求凸包最短距离)

Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9...
  • dgghjnjk
  • dgghjnjk
  • 2016-06-08 23:04
  • 184

poj 3608 Bridge Across Islands(卡壳旋转求两个多边形的最近点对)

Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7672   Acce...
  • u010527492
  • u010527492
  • 2013-12-14 17:24
  • 590

poj 3608 Bridge Across Islands(旋转卡壳求俩凸包间最小间距)

神呐!!!!!!! 折腾了两天多!!!(其实有效率地去想去写应该一天吧)。。 原来的想法很淳朴(好吧,很笨),就是找出来卡壳的那两条线,然后算出每条线离它相应的那条边的角度,然后旋转。 分为三种情况 ...
  • zxy_snow
  • zxy_snow
  • 2011-06-12 22:31
  • 1773

poj3608 Bridge Across Islands (旋转卡壳之两凸包最短距)

题目链接:http://poj.org/problem?id=3608 题意:求两个凸包的最短距离。 在之前不知道还要求凸包,就直接求卡壳了,果断wa了;还有在求卡壳时我用角度去比较它们的...
  • ssslpk
  • ssslpk
  • 2012-08-03 00:17
  • 653

poj 3608 Bridge Across Islands 旋转卡壳(两个凸包的最近距离)

代码:
  • a601025382s
  • a601025382s
  • 2014-07-20 10:26
  • 520

poj3608Bridge Across Islands【旋转卡壳】

Language: Default Bridge Across Islands Time Limit: 1000MS   Memory Limit: 65536K ...
  • R1986799047
  • R1986799047
  • 2015-09-19 09:15
  • 646

PKU 3608 Bridge Across Islands 凸包+旋转卡壳

Bridge Across IslandsDescriptionThousands of thousands years ago there was a small kingdom located ...
  • qq503884564
  • qq503884564
  • 2011-02-16 17:23
  • 385
    个人资料
    • 访问:327273次
    • 积分:8806
    • 等级:
    • 排名:第2521名
    • 原创:574篇
    • 转载:13篇
    • 译文:0篇
    • 评论:36条
    我的链接
    最新评论