1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
| #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;
namespace GEO{ #define cdou const double & const double EPS=1e-16,INF=1e9; inline int sgn(cdou key){return fabs(key)<EPS? 0:(key<0? -1:1);} struct Vector{ double x,y; Vector(cdou _x=0,cdou _y=0):x(_x),y(_y){} inline Vector operator *(cdou k)const{return Vector(x*k,y*k);} inline double len()const{return sqrt(x*x+y*y);} inline friend double cross(const Vector &u,const Vector &v){ return u.x*v.y-u.y*v.x; } inline friend double dot(const Vector &u,const Vector &v){ return u.x*v.x+u.y*v.y; } inline Vector operator -()const{return Vector(-x,-y);} }; struct Point{ double x,y; Point(cdou _x=0,cdou _y=0):x(_x),y(_y){} friend double distPoint(const Point &u,const Point &v){ return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y)); } inline Point operator +(const Vector &v)const{return Point(x+v.x,y+v.y);} inline Point operator -(const Vector &v)const{return Point(x-v.x,y-v.y);} inline Vector operator -(const Point &v)const{return Vector(x-v.x,y-v.y);} inline bool operator ==(const Point &v)const{return !sgn(x-v.x) && !sgn(y-v.y);} inline bool operator !=(const Point &v)const{return sgn(x-v.x) || sgn(y-v.y);} }; struct Line{ Point p;Vector d; double ang; Line(){} Line(const Point &_p,const Vector &_d):p(_p),d(_d){} Line(const Point &s,const Point &t):p(s),d(t-s){} void getAngle(){ang=atan2(d.y,d.x);} }; bool ifSegInter(const Point &u1,const Point &u2,const Point &v1,const Point &v2){ int re1=sgn(cross(v1-u1,u2-u1)*cross(v2-u1,u2-u1)), re2=sgn(cross(u1-v1,v2-v1)*cross(u2-v1,v2-v1)); return re1<=0 && re2<=0; } int fixSide(const Point &s,const Point &t,const Point &p){return sgn(cross(t-s,p-s));} int fixSide(const Line &l,const Point &p){return sgn(cross(l.d,p-l.p));} Point getLineInter(const Line &u,const Line &v){ double h=cross(u.p-v.p,v.d),d=cross(u.d,v.d); if(!sgn(d)) return u.p; return u.p-u.d*(h/d); } bool cmpPointToX(const Point &u,const Point &v){return sgn(u.x-v.x)? sgn(u.x-v.x)<0:sgn(u.y-v.y)<0;} bool cmpLineToAngle(const Line &u,const Line &v){return sgn(u.ang-v.ang)<0;}
bool buildConvex(Point *org,int n,Point *res,int &m){ if(n<=2) return false; m=0; sort(org,org+n,cmpPointToX); for(int i=0;i<n;i++){ while(m>1 && fixSide(res[m-2],res[m-1],org[i])<=0) m--; res[m++]=org[i]; } int m0=m; for(int i=n-2;~i;i--){ while(m>m0 && fixSide(res[m-2],res[m-1],org[i])<=0) m--; res[m++]=org[i]; } m--; return m>2; } bool getSI(Line *lin,int n,Point *rep,Line *rel,int &m){ for(int i=0;i<n;i++) lin[i].getAngle(); sort(lin,lin+n,cmpLineToAngle); int indl=0,indr=0; rel[indr++]=lin[0]; for(int i=1;i<n;i++){ while(indr-indl>1 && fixSide(lin[i],rep[indr-2])<=0) indr--; while(indr-indl>1 && fixSide(lin[i],rep[indl])<=0) indl++; if(!sgn(cross(lin[i].d,rel[indr-1].d))){ if(fixSide(rel[indr-1],lin[i].p)>0){ rel[indr-1]=lin[i]; rep[indr-2]=getLineInter(rel[indr-1],rel[indr-2]); } continue; } rel[indr++]=lin[i]; rep[indr-2]=getLineInter(rel[indr-1],rel[indr-2]); } while(indr-indl>1 && fixSide(rel[indl],rep[indr-2])<=0) indr--; rep[indr-1]=getLineInter(rel[indr-1],rel[indl]); m=indr-indl; if(m<=2) return false; for(int i=indl;i<indr;i++) rel[i-indl]=rel[i],rep[i-indl]=rep[i]; return true; } double distLinePoint(const Line &l,const Point &p){ return fabs(cross(l.d,p-l.p))/l.d.len(); } double distSegPoint(const Point &s1,const Point &s2,const Point &p){ if(sgn(dot(p-s1,s2-s1))>=0 && sgn(dot(p-s2,s1-s2))>=0) return distLinePoint(Line(s1,s2),p); return min(distPoint(p,s1),distPoint(p,s2)); } } using namespace GEO;
const int N=1e4+10;
int n,m; Point p1[N],p2[N];
#define debug(it) it.x,it.y
double directDist(const Point &s,const Point &t,const Point &p){ return cross(t-s,p-s)/distPoint(s,t); } int main(){ while(~scanf("%d%d",&n,&m) && n && m){ 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); if(fixSide(p1[0],p1[1],p1[2])<0) reverse(p1,p1+n); if(fixSide(p2[0],p2[1],p2[2])<0) reverse(p2,p2+m); p1[n]=p1[0],p2[m]=p2[0]; double ans=1e9; for(int i=0,j=0;i<n;i++){ while(sgn(directDist(p1[i],p1[i+1],p2[j])-directDist(p1[i],p1[i+1],p2[j+1]))<0) j=(j+1)%m; ans=min(ans,distSegPoint(p1[i],p1[i+1],p2[j])); ans=min(ans,distSegPoint(p1[i],p1[i+1],p2[j+1])); } for(int i=0,j=0;i<m;i++){ while(sgn(directDist(p2[i],p2[i+1],p1[j])-directDist(p2[i],p2[i+1],p1[j+1]))<0) j=(j+1)%n; ans=min(ans,distSegPoint(p2[i],p2[i+1],p1[j])); ans=min(ans,distSegPoint(p2[i],p2[i+1],p1[j+1])); } printf("%.6f\n",ans); } return 0; }
|