题意:
给出两个线段的端点,让你求这两条线段的最近距离和最远距离。
思路:
最近距离只可能出现在端点到垂足或者端点到端点上,最长距离只会出现在端点到端点上。
代码:
#include<cstdio>
#include<cstring>
#include<climits>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<sstream>
using namespace std;
const double eps = 1e-5;
const int maxn=10000;
int cmp(double x)
{
if(fabs(x) < eps) return 0;
if(x > 0) return 1;
return -1;
}
struct point
{
double x, y;
point() {};
point(double a, double b) : x(a), y(b) {};
friend point operator + (const point & a, const point &b)
{
return point(a.x + b.x , a.y + b.y );
}
friend point operator - (const point & a, const point &b)
{
return point(a.x - b.x, a.y - b.y);
}
friend point operator * (const point & a, const double &b)
{
return point(a.x * b, a.y * b);
}
friend point operator / (const point & a, const double &b)
{
return point(a.x / (b+eps), a.y / (b + eps));
}
friend bool operator == (const point& a, const point& b)
{
return cmp(a.x - b.x) == 0 && cmp(a.y - b.y) == 0;
}
double norm()
{
return sqrt(x*x + y*y);
}
};
double det(const point &a,const point &b)
{
return a.x * b.y - a.y * b.x;
}
double dot(point a, point b)
{
return a.x * b.x + a.y * b.y;
}
void PointPro(point p,point s,point t,point &cp)
{
double r = dot((t - s),(p - s))/dot(t-s,t - s);
cp = s + (( t - s) * r);
}
bool On(point p, point s, point t)
{
return cmp(det(p-s, t - s)) == 0&& cmp(dot(p-s,p-t))<=0;
}
struct polygon
{
int n;
point a[maxn];
polygon() {};
double area()
{
// printf("nnnnnnnnnnnnnnnnnnnnnnnn%d\n", n);
double sum = 0;
a[n] = a[0];
for(int i = 0; i < n; i++)
{
// puts("JJJJJ");
sum += det(a[i + 1], a[i]);
}
return sum / 2;
}
point center()
{
point ans = point(0, 0);
// printf("a = %lf\n",area());
if(cmp(area()) == 0) return ans;
a[n] = a[0];
for(int i = 0; i < n; i++)
{
ans = ans +(a[i] + a[i + 1]) * det(a[i + 1], a[i]);
}
return ans / area() / 6.0;
}
};
double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double dis_point_segment(const point& p, const point& s, const point& t)
{
if(cmp(dot(p-s, t-s))<0) return (p-s).norm();
if(cmp(dot(p-t, s-t))<0) return (p-t).norm();
return fabs(det(s-p, t-p)/(s-t).norm());
}
struct line
{
point a, b;
line(const point& a, const point& b) : a(a), b(b) {}
};
bool line_jiao(line a, line b)
{
bool res=true;
res=res&&(cmp(det(a.b-a.a,b.a-a.a))*cmp(det(a.b-a.a,b.b-a.a))<0);
res=res&&(cmp(det(a.a-a.b,b.a-a.b))*cmp(det(a.a-a.b,b.b-a.b))<0);
res=res&&(cmp(det(b.b-b.a,a.a-b.a))*cmp(det(b.b-b.a,a.b-b.a))<0);
res=res&&(cmp(det(b.a-b.b,a.a-b.b))*cmp(det(b.a-b.b,a.b-b.b))<0);
return res;
}
double _max(double a,double b)
{
if(cmp(a-b)>0)
return a;
return b;
}
double _min(double a,double b)
{
if(cmp(a- b)>0)
return b;
return a;
}
int main()
{
//freopen("in.txt","r",stdin);
//printf("%d\n",line_jiao(line(point(0,0),point(2,0)),line(point(1,1),point(1,-1))));
point a,b,c,d;
int cas=1;
while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y)!=EOF)
{
double minans=1000000000000.0;
double maxans=-1000000000000.0;
minans=_min(minans,dis_point_segment(a,c,d));
minans=_min(minans,dis_point_segment(b,c,d));
minans=_min(minans,dis_point_segment(c,a,b));
minans=_min(minans,dis_point_segment(d,a,b));
minans=_min(minans,dis(a,c));
minans=_min(minans,dis(a,d));
minans=_min(minans,dis(b,c));
minans=_min(minans,dis(b,d));
if(line_jiao(line(a, b), line(c, d)))
minans=0.0;
maxans=_max(maxans,dis(a,c));
maxans=_max(maxans,dis(a,d));
maxans=_max(maxans,dis(b,c));
maxans=_max(maxans,dis(b,d));
if(a==b&&c==d)
minans=maxans;
printf("Case #%d: %.3lf %.3lf\n",cas++,maxans,minans);
}
return 0;
}