网上代码,卡壳部分的实现还未太懂
先留着
http://blog.sina.com.cn/s/blog_732dd9320100sjtv.html
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define N 10015
#define PR 1e-8
struct TPoint
{
double x,y;
TPoint(){};
TPoint(double _x,double _y):x(_x),y(_y){}
TPoint operator-(const TPoint p){return TPoint(x-p.x,y-p.y);}
}s;
struct TPolygon
{
int n;
TPoint p[N];
}ply1,ply2;
int dblcmp(double a) {return fabs(a)<PR?0:a>0?1:-1;}
double MIN(double a,double b) {return a<b?a:b;}
double dist(TPoint a,TPoint b)//两点距
{
TPoint c(a-b);
return sqrt(c.x*c.x+c.y*c.y);
}
double cross(TPoint a,TPoint b,TPoint c)//叉积
{
TPoint s(b-a),t(c-a);
return s.x*t.y-s.y*t.x;
}
bool cmop(TPoint a,TPoint b)//x、y排序
{
if(fabs(a.x-b.x)<PR) return a.y<b.y;
else return a.x<b.y;
}
bool cmp(TPoint a,TPoint b)//叉积内排序
{
int d1=dblcmp(cross(s,a,b));
return d1>0||(d1==0&&dist(s,a)<dist(s,b));
}
TPolygon graham(TPolygon ply)//凸包
{
int i,j,k;
sort(ply.p,ply.p+ply.n,cmop);
s=ply.p[0]; k=2;
sort(ply.p+1,ply.p+ply.n,cmp);
for(i=2,k=2;i<ply.n;i++)
{
while(k>1&&(dblcmp(cross(ply.p[k-2],ply.p[i],ply.p[k-1])))>=0) k--;
ply.p[k++]=ply.p[i];
}
ply.n=k;
return ply;
}
double disps(TPoint a,TPoint b,TPoint c)//点到线段的最近距离
{
TPoint s(a-b),t(c-b);
if(s.x*t.x+s.y*t.y<0) return dist(a,b);
s=(a-c); t=(b-c);
if(s.x*t.x+s.y*t.y<0) return dist(a,c);
return fabs(cross(a,b,c))/(dist(b,c));
}
double disss(TPoint a,TPoint b,TPoint c,TPoint d)//两条线段最近距离
{
return MIN(MIN(disps(a,c,d),disps(b,c,d)),MIN(disps(c,a,b),disps(d,a,b)));
}
double solve(TPolygon pl,TPolygon pr,int p,int q)//旋转卡壳,求凸边形最近距离
{
int i;
double tmp,min=1e90;
pl.p[pl.n]=pl.p[0]; pr.p[pr.n]=pr.p[0];
for(i=0;i<pl.n;i++)
{
while((tmp=cross(pl.p[p+1],pr.p[q+1],pl.p[p])-cross(pl.p[p+1],pr.p[q],pl.p[p]))>PR)
q=(q+1)%pr.n;
if(tmp<-PR) min=MIN(min,disps(pr.p[q],pl.p[p],pl.p[p+1]));
else min=MIN(min,disss(pl.p[p],pl.p[p+1],pr.p[q],pr.p[q+1]));
p=(p+1)%pl.n;
}
return min;
}
void gettop(TPolygon pl,TPolygon pr,int &l,int &r)//得到最下和最上点
{
int i;
l=r=0;
for(i=0;i<pl.n;i++)
{
if((dblcmp(pl.p[i].y-pl.p[l].y))<0) l=i;
}
for(i=0;i<pr.n;i++)
{
if((dblcmp(pr.p[i].y-pr.p[r].y))>0) r=i;
}
}
int main()
{
while(scanf("%d%d",&ply1.n,&ply2.n),ply1.n&&ply2.n)
{
int i,l,r;
for(i=0;i<ply1.n;i++) scanf("%lf%lf",&ply1.p[i].x,&ply1.p[i].y);
for(i=0;i<ply2.n;i++) scanf("%lf%lf",&ply2.p[i].x,&ply2.p[i].y);
ply1=graham(ply1);
ply2=graham(ply2);
gettop(ply1,ply2,l,r);
double mindis=MIN(solve(ply1,ply2,l,r),solve(ply2,ply1,r,l));//最近距离
printf("%.5lf\n",mindis);
}
return 0;
}