对,我今天又没吃药。
喜闻乐见的计算几何题,WA几十发就是爽!
思路很简单,然后程序写的我就萌萌哒了
- 两条线段没有交点,或者互相平行,或者至少有一条平行于x轴的线段,则答案为0.00
- 如果有一条线段覆盖了另一条,则答案为0.00
- 否则答案就是交点和交点上方最低的点和过这个点做的平行与x轴的线围成的三角形的距离
对,思路非常简单,谁也不会想错
就是写不对!
我已弃疗
附AC代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#define INF (999999.9)
using namespace std;
const double eps = 1e-8;
const double pi = acos(-1.0);
inline bool isint(double x){return fabs((x-int(x+0.5))) < eps;}
inline int cmp(double x){
if (fabs(x)<eps) return 0;
if (x>0) return 1;
return -1;
}
struct point{
double x,y;
point(double x=0,double y=0):x(x),y(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 point &b){return point(a.x-b.x,a.y-b.y);}
friend bool operator == (const point &a,const point &b){return cmp(a.x-b.x)==0 && cmp(a.y-b.y)==0;}
friend bool operator != (const point &a,const point &b){return cmp(a.x-b.x)!=0 || cmp(a.y-b.y)!=0;}
friend point operator * (const point &a,const double &b){return point(a.x*b,a.y*b);}
friend point operator * (const double &a,const point &b){return point(a*b.x,a*b.y);}
friend point operator / (const point &a,const double &b){return point(a.x/b,a.y/b);}
friend double operator * (const point &a ,const point &b) { return a.x*b.y-b.x*a.y; }
inline double len() const {return sqrt(x*x+y*y);}
inline point rotate(double rad) const {return point(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));}
#ifdef DEBUG
void print(string debug="debug"){cout<<debug<<" "<<x<<" "<<y<<endl;}
#endif
};
typedef point vec;
inline double dot(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
inline double dis(const point &a,const point &b){return (a-b).len();}
inline double angle(const point &a,const point &b){return acos(dot(a,b)/a.len()/b.len());}
inline double area(point a,point b,point c){return (b-a)*(c-a)/2.0;}
point CircumCenter(point a,point b,point c){//三角形外心
vec A=b-a , B=c-a;
double c1=A.len()*A.len()/2.0 , c2=B.len()*B.len()/2.0;
return point(a.x+(c1*B.y-c2*A.y)/(A*B),a.y+(A.x*c2-B.x*c1)/(A*B));
}
//点与直线相关
//L 是直线的方向向量
inline double dis_P2L(const point p,const vec L){return p*L/L.len();}
point projection(const point p,const vec L){return L*(dot(L,p)/dot(L,L));}//投影点
point getIntersection(point p,vec v,point q,vec w){//v,w是方向向量,p,q是直线上任意两点
vec u=p-q;
double t=(w*u)/(v*w);
return p+v*t;
}
bool parallel(point a,point b,point c,point d){//平行
return !(cmp((a-b)*(c-d)));
}
//点与线段相关
bool onSegment(point p,point a1,point a2){
return cmp((a1-p)*(a2-p))==0 && cmp(dot(a1-p,a2-p))<0;
}
bool seg_intersection(point a1,point a2,point b1,point b2){
if (onSegment(a1,b1,b2) || onSegment(a2,b1,b2) ||onSegment(b1,a1,a2)||onSegment(b2,a1,a2)) return true;//端点在另一条线段上
if (a1==b1 || a1==b2 || a2==b1 || a2==b2) return true;//端点相同
double c1=(a2-a1)*(b1-a1),c2=(a2-a1)*(b2-a1),c3=(b2-b1)*(a1-b1),c4=(b2-b1)*(a2-b1);
return cmp(c1)*cmp(c2)<0 && cmp(c3)*cmp(c4)<0;//规范相交
}
bool under(point p,point a,point b){
if (b.x<a.x) swap(a,b);
if (onSegment(p,a,b)) return true;
if (!seg_intersection(a,b,p,point(p.x,20000.0))) return false;
if (cmp(getIntersection(p,point(0,1),a,a-b).y-p.y)>0) return true;
return false;
}
int main (int argc, char *argv[])
{
int n;
scanf("%d",&n);
while (n--){
double ans;
double x1,y1,x2,y2,x3,y3,x4,y4;
cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
point a,b,c,d;
a=point(x1,y1);
b=point(x2,y2);
c=point(x3,y3);
d=point(x4,y4);
if (!seg_intersection(a,b,c,d)){
printf("0.00
");
continue;
}
if (a.y==b.y || c.y==d.y){//cout<<"w"<<endl;
printf("0.00
");
continue;
}
if (parallel(a,b,c,d)){//cout<<"w"<<endl;
printf("0.00
");
continue;
}
point ins=getIntersection(a,a-b,c,c-d);
//ins.print("ins");
point p;
double ymin=900000;
double s=0.0;
int cnt=0;
if (a.y>ins.y&&a.y<ymin&&!under(a,c,d)&&seg_intersection(point(-100001,a.y),point(10001,a.y),c,d)) ymin=a.y , p=getIntersection(a,vec(1,0),c,c-d) , s=area(a,p,ins);
if (b.y>ins.y&&b.y<ymin&&!under(b,c,d)&&seg_intersection(point(-100001,b.y),point(10001,b.y),c,d)) ymin=b.y , p=getIntersection(b,vec(1,0),c,c-d) , s=area(b,p,ins);
if (c.y>ins.y&&c.y<ymin&&!under(c,a,b)&&seg_intersection(point(-100001,c.y),point(10001,c.y),a,b)) ymin=c.y , p=getIntersection(c,vec(1,0),a,a-b) , s=area(c,p,ins);
if (d.y>ins.y&&d.y<ymin&&!under(d,a,b)&&seg_intersection(point(-100001,d.y),point(10001,d.y),a,b)) ymin=d.y , p=getIntersection(d,vec(1,0),a,a-b) , s=area(d,p,ins);
printf("%.2lf
",fabs(s));
}
return 0;
}