给两个凸包,求出这两个凸包的最近距离。这题wa的我是一塌糊涂啊,说多了都是泪,后来稀里糊涂的就改对了。。。
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
#include<queue>
#include<math.h>
#include<cstdio>
using namespace std;
const double eps=1e-9;
struct point
{
double x,y;
point () {}
point (double xx,double yy): x(xx),y(yy) {}
}p1[10010],p2[10010];
point operator + (point a,point b) { return point(a.x+b.x,a.y+b.y); }
point operator - (point a,point b) { return point(a.x-b.x,a.y-b.y); }
point operator * (point a,point b) { return point(a.x*b.x,a.y*b.y); }
point operator / (point a,point b) { return point(a.x/b.x,a.y/b.y); }
double cross(point a,point b,point op)
{
return (op.x-a.x)*(op.y-b.y)-(op.y-a.y)*(op.x-b.x);
}
double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
double dist_p_to_p(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double dist_p_to_seg(point c,point a,point b)
{
point ab=b-a;
point ac=c-a;
double f=dot(ab,ac);
if(f<0) return dist_p_to_p(a,c);
double D=dot(ab,ab);
if(f>D) return dist_p_to_p(b,c);
f=f/D;
point d=point(a.x+f*ab.x,a.y+f*ab.y);
return dist_p_to_p(d,c);
}
double dist_seg_to_seg(point p1, point p2, point p3, point p4)
{
return min(min(dist_p_to_seg(p1, p3, p4), dist_p_to_seg(p2, p3, p4)),
min(dist_p_to_seg(p3, p1, p2), dist_p_to_seg(p4, p1, p2)));
}
double rc(point pp[],point qq[],int n,int m)
{
int q=0;
int p=0;
for(int i=0;i<n;i++)
if(pp[i].y-pp[p].y<-eps)
p=i;
for(int i=0;i<m;i++)
if(qq[i].y-qq[q].y>eps)
q=i;
pp[n]=pp[0];
qq[m]=qq[0];
double tmp,ans=1e99;
for(int i=0;i<n;i++)
{
while((tmp=cross(pp[p+1],qq[q+1],pp[p])-cross(pp[p+1],qq[q],pp[p]))>eps)
q=(q+1)%m;
if(tmp<-eps)
ans=min(ans,dist_p_to_seg(qq[q],pp[p],pp[p+1]));
else
ans=min(ans,dist_seg_to_seg(pp[p],pp[p+1],qq[q],qq[q+1]));
p=(p+1)%n;
}
return ans;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0 && m==0) break;
for(int i=0;i<n;i++)
scanf("%lf%lf",&p1[i].x,&p1[i].y);
for(int i=0;i<m;i++)
scanf("%lf%lf",&p2[i].x,&p2[i].y);
double ans=min(rc(p1,p2,n,m),rc(p2,p1,m,n));
printf("%.5lf\n",ans);
}
return 0;
}