以下所有文章均转载( http://blog.csdn.net/acmaker/article/details/3176910) 转载请注明出处!
考虑如下的算法, 算法的输入是两个分别有 m 和 n 个顺时针给定顶点的凸多边形 P 和 Q。
以上是转载。。以下是原创。。
上面是按顺时针存的凸包也是按顺时针旋转的平行线,网上很多是逆时针的凸包却写着顺时针的做法,但代码依旧A了,,不是很理解。。
逆时针 改反一点 依旧A。。。
感觉自己 的是对的吧。。。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 10010 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-9; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 struct Point 18 { 19 double x,y; 20 Point(double x=0,double y=0):x(x),y(y) {} //构造函数 方便代码编写 21 }p[N],q[N]; 22 typedef Point pointt; 23 pointt operator + (Point a,Point b) 24 { 25 return Point(a.x+b.x,a.y+b.y); 26 } 27 pointt operator - (Point a,Point b) 28 { 29 return Point(a.x-b.x,a.y-b.y); 30 } 31 int dcmp(double x) 32 { 33 if(fabs(x)<eps) return 0; 34 else return x<0?-1:1; 35 } 36 bool operator == (const Point &a,const Point &b) 37 { 38 return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0; 39 } 40 double dot(Point a,Point b) 41 { 42 return a.x*b.x+a.y*b.y; 43 } 44 double dis(Point a) 45 { 46 return sqrt(dot(a,a)); 47 } 48 double cross(Point a,Point b) 49 { 50 return a.x*b.y-a.y*b.x; 51 } 52 void anticlock(Point p[],int n) 53 { 54 for(int i = 0 ; i < n-2 ; i++) 55 { 56 double k = cross(p[i+1]-p[0],p[i+2]-p[0]); 57 if(dcmp(k)>0) return ; 58 else if(dcmp(k)<0) 59 { 60 reverse(p,p+n); 61 return ; 62 } 63 } 64 } 65 double distoline(Point a,Point b,Point c) 66 { 67 if(dcmp(dis(a-b))==0) return dis(a-c); 68 if(dcmp(dot(a-b,a-c))<0) return dis(a-c); 69 if(dcmp(dot(b-a,b-c))<0) return dis(b-c); 70 return fabs(cross(a-b,a-c))/dis(a-b); 71 } 72 double dist(Point a,Point b,Point c,Point d) 73 { 74 double ans = distoline(a,b,c); 75 ans = min(ans,distoline(a,b,d)); 76 ans = min(ans,distoline(c,d,a)); 77 ans = min(ans,distoline(c,d,b)); 78 return ans; 79 } 80 double mul(Point a,Point b,Point c) 81 { 82 return cross(b-a,c-a); 83 } 84 double solve(Point p[],int n,Point q[],int m) 85 { 86 int i; 87 int miny = 0,maxy = 0; 88 for(i = 0;i < n; i++) 89 { 90 if(p[i].y<p[miny].y) 91 miny = i; 92 } 93 for(i =0 ; i< m ; i++) 94 if(q[i].y>q[maxy].y) maxy = i; 95 double ans = dis(p[miny]-q[maxy]); 96 for(i = 0 ;i < n; i++) 97 { 98 double tmp; 99 while(tmp = mul(p[miny],p[miny+1],q[maxy+1])-mul(p[miny],p[miny+1],q[maxy])>eps) 100 maxy = (maxy+1)%m; 101 if(dcmp(tmp)>0) ans = min(ans,distoline(p[miny],p[miny+1],q[maxy]));//这里如果写成<0 画图可以看出是顺时针的做法 就算不加这句直接算下面的也能A。。 102 else 103 ans = min(ans,dist(p[miny],p[miny+1],q[maxy],q[maxy+1]));//边-边 104 miny = (miny+1)%n; 105 } 106 return ans; 107 } 108 int main() 109 { 110 int i,n,m; 111 while(scanf("%d%d",&n,&m)&&n&&m) 112 { 113 for(i = 0 ; i < n ; i++) 114 scanf("%lf%lf",&p[i].x,&p[i].y); 115 for(i = 0 ;i < m ;i++) 116 scanf("%lf%lf",&q[i].x,&q[i].y); 117 anticlock(p,n); 118 anticlock(q,m); 119 p[n] = p[0]; 120 121 q[m] = q[0]; 122 double ans = min(solve(p,n,q,m),solve(q,m,p,n)); 123 124 printf("%.5f\n",ans); 125 } 126 return 0; 127 }