zoukankan      html  css  js  c++  java
  • POJ3608

    计算两个凸包之间的最小距离,旋转卡壳法详解在旋转卡壳的用法之计算两个凸 包上的最近距离

    #include <iostream>
    #include<cstdio>
    #include<string.h>
    #include<cmath>
    using namespace std;
    const double eps=1e-10;
    const double INF=1e10;
    struct point
    {
        double x,y;
        point (double a=0,double b=0)
        {
            x=a;
            y=b;
        }
    };
    double min_val(double a,double b)
    {
        return a>b?b:a;
    }
    int dcmp(double a)
    {
        if(fabs(a)<eps)return 0;
        else return a>0?1:-1;
    }
    point operator -(point a,point b){ return point (a.x-b.x,a.y-b.y); }
    bool operator ==(const point &a,const point &b)
    {
        return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
    }
    double cross(point a,point b)
    {
        return a.x*b.y-a.y*b.x;
    }
    void readdate(point a[],int n,point b[],int m)
    {
        int i;
        for(i=0;i<n;i++)
        scanf("%lf%lf",&a[i].x,&a[i].y);
        for(i=0;i<m;i++)
        scanf("%lf%lf",&b[i].x,&b[i].y);
    }
    void change(point a[],int b)
    {
        int i;
        point temp;
        for(i=0;i<b/2;i++)
        {
            temp=a[i];
            a[i]=a[b-1-i];
            a[b-1-i]=temp;
        }
    }
    void work(point p[],int n,point q[],int m)
    {
        int i;
        for(i=0;i<n-2;i++)
        if(dcmp(cross(p[i+1]-p[i],p[i+2]-p[i])>0)) break;
        else if(dcmp(cross(p[i+1]-p[i],p[i+2]-p[i])<0))
        {
            change(p,n);
            break;
        }
        for(i=0;i<m-2;i++)
        if(dcmp(cross(q[i+1]-q[i],q[i+2]-q[i])>0))break;
        else if(dcmp(cross(q[i+1]-q[i],q[i+2]-q[i])<0))
        {
            change(q,m);
            break;
        }
    }
    double Dot(point A,point B){return A.x*B.x+A.y*B.y;}
    double Length(point A){return sqrt(Dot(A,A));}
    double dist(point a,point b,point p)
    {
        if(a==b) return Length(p-a);
        point v1=b-a,v2=p-a,v3=p-b;
        if(dcmp(Dot(v1,v2))<0)return Length(v2);
        if(dcmp(Dot(v1,v3))>0)return Length(v3);
        return fabs(cross(v1,v2))/Length(v1);
    
    }
    double Mid(point a1,point a2,point b1,point b2)
    {
        return min_val(min_val(dist(a1,a2,b1),dist(a1,a2,b2)),
                       min_val(dist(b1,b2,a1),dist(b1,b2,a2)));
    }
    double solve(point P[],int n,point Q[],int m)
    {
        double ans=INF,temp;
        int i,minP=0,maxQ=0;
        for(i=0;i<n;i++)
        if(P[i].y<P[minP].y)
        minP=i;
        for(i=0;i<m;i++)
        if(Q[i].y>Q[maxQ].y)
        maxQ=i;
        Q[m]=Q[0];
        P[n]=P[0];
        for(i=0;i<n;i++)
        {
            while((temp=cross(Q[maxQ+1]-P[minP+1],P[minP]-P[minP+1])
                   -cross(Q[maxQ]-P[minP+1],P[minP]-P[minP+1]))>eps)
            maxQ=(maxQ+1)%m;
            if(temp<-eps)
                ans=min_val(ans,dist(P[minP],P[minP+1],Q[maxQ]));
            else ans=min_val(ans,Mid(P[minP],P[minP+1],Q[maxQ],Q[maxQ+1]));
            minP=(minP+1)%n;
        }
        return ans;
    }
    int main()
    {
        point p[10005],q[10005];
        int n,m;
        double a,b;
        while(scanf("%d%d",&n,&m)==2)
        {
            if(m==0&&n==0)break;
            readdate(p,n,q,m);
            work(p,n,q,m);
           a=solve(p,n,q,m);
           b=solve(q,m,p,n);
           printf("%.5lf
    ",min_val(a,b));
        }
        return 0;
    }
    

  • 相关阅读:
    git merge 和 git rebase 的使用场景
    Xcode 报错:解决 Could not attach to pid : "xx" 不重开工程的杀手锏
    软件设计模式的7条原则
    iOS开发信号量的使用
    利用SAMKeyChain生成唯一设备号
    iOS Fundation和CoreFoundation的对象转换内存管理权问题
    已有的PHP安装gd扩展
    centos7 编译安装 php7.4
    Nacos集群模式部署步骤
    搭建 Apache RocketMQ 单机环境
  • 原文地址:https://www.cnblogs.com/Opaser/p/3662070.html
Copyright © 2011-2022 走看看