#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
#define min(a, b) ((a) < (b) ? (a): (b))
#define EPS 1e-8
const int MAXN = 10010;
struct Point
{
double x, y;
Point(){}
Point(double _x, double _y):x(_x), y(_y){}
void input()
{
scanf("%lf%lf", &x, &y);
}
};
inline double pdis(Point a, Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
inline double dotcross(Point p0, Point p1, Point p2)
{
return (p1.x - p0.x) * (p2.x - p0.x) + (p1.y - p0.y) * (p2.y - p0.y);
}
inline double difcross(Point p0, Point p1, Point p2)
{
return (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
Point p[MAXN], q[MAXN];
int np, nq;
inline double p2segline(Point a, Point p1, Point p2)
{
return fabs(difcross(a, p1, p2) / pdis(p1, p2));
}
inline double p2seg(Point a, Point p1, Point p2)
{
if(dotcross(p1, p2, a) < -EPS) return pdis(a, p1);
if(dotcross(p2, p1, a) < -EPS) return pdis(a, p2);
return p2segline(a, p1, p2);
}
inline double FourPoints(Point p1, Point p2, Point q1, Point q2)
{
double ans1 = min(p2seg(p1, q1, q2), p2seg(p2, q1, q2));
double ans2 = min(p2seg(q1, p1, p2), p2seg(q2, p1, p2));
return min(ans1, ans2);
}
inline double solve(Point *p, Point *q, int np, int nq)
{
p[np] = p[0];
q[nq] = q[0];
int sp = 0, sq = 0;
for(int i = 0; i < np; i ++)
{
if(p[i].y + EPS < p[sp].y) sp = i;
}
for(int i = 0; i < nq; i ++)
{
if(q[i].y + EPS < q[sp].y) sq = i;
}
double tmp, ans = 1e99;
for(int i = 0; i < np; i ++)
{
while((tmp = difcross(q[sq], p[sp], p[sp+1]) - difcross(q[sq+1], p[sp], p[sp+1])) < -EPS)
sq = (sq + 1 ) % nq;
if(tmp > EPS)
ans = min(ans, p2seg(q[sq], p[sp], p[sp+1]));
else
ans = min(ans, FourPoints(p[sp], p[sp+1], q[sq], q[sq+1]));
sp = (sp + 1)% np;
}
return ans;
}
inline double NearestPoints(Point *p, Point *q, int np, int nq)
{
return min(solve(p, q, np, nq), solve(q, p, nq, np));
}
int main()
{
while(~scanf("%d%d", &np, &nq))
{
if(np ==0 && np ==0) break;
for(int i = 0; i < np; i ++) p[i].input();
for(int i = 0; i < nq; i ++) q[i].input();
double ans = NearestPoints(p, q, np, nq);
printf("%lf\n", ans);
}
return 0;
}
旋转卡壳求凸包间的最短距离 POJ 3608
最新推荐文章于 2021-08-29 17:10:02 发布