真的不是简单的问题啊!
雨水从上方落下。接不到雨的情况:
注意这两种是可以接到雨的
都判断清楚了这题就好做了。
//Memory: 192K
//Time: 32MS
#include <stdio.h>
#include <iostream>
#include <math.h>
#define EP 1E-6
#define INF 1E100
using namespace std;
struct POINT
{
double x,y;
};
struct LINESEG
{
POINT s,e;
};
struct LINE
{
double a,b,c;
POINT A,B;
LINE(){};
LINE(POINT _a,POINT _b)
{
A=_a;
B=_b;
a=B.y-A.y;
b=A.x-B.x;
c=B.x*A.y-A.x*B.y;
};
};
double multiply(POINT sp,POINT ep,POINT op)//叉积
{
return (sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y);
}
bool intersect(LINESEG u,LINESEG v)//求线段交点
{
return ((max(u.s.x,u.e.x)>=min(v.s.x,v.e.x)) &&
(max(v.s.x,v.e.x)>=min(u.s.x,u.e.x)) &&
(max(u.s.y,u.e.y)>=min(v.s.y,v.e.y)) &&
(max(v.s.y,v.e.y)>=min(u.s.y,u.e.y)) &&
(multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0) &&
(multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0));
}
int main()
{
//freopen("data.txt","r",stdin);
//freopen("out.txt","w",stdout);
int cas,i;
double ans;
POINT p[5];
LINESEG l1,l2;
scanf("%d",&cas);
while(cas--)
{
ans=0;
int my=0;
double lx=0;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p[1].x,&p[1].y,&p[2].x,&p[2].y,&p[3].x,&p[3].y,&p[4].x,&p[4].y);
l1.s=p[1];l1.e=p[2];
l2.s=p[3];l2.e=p[4];
if(intersect(l1,l2))
{
LINE t[3];
t[1]=LINE(p[1],p[2]);
t[2]=LINE(p[3],p[4]);
if(fabs(t[1].b/t[1].a-t[2].b/t[2].a)>EP)
{
double d=t[1].a*t[2].b-t[2].a*t[1].b;
p[0].x=(t[2].c*t[1].b-t[1].c*t[2].b)/d;
p[0].y=(t[2].a*t[1].c-t[1].a*t[2].c)/d;
for(i=1;i<=4;i++)
{
if(p[i].y>p[0].y)
{
if(my==0)
my=i;
else
{
if(p[i].y<p[my].y)
{
lx=p[i].x+(t[(my+1)/2].b*p[i].y+t[(my+1)/2].c)/t[(my+1)/2].a;
if((multiply(p[i],p[my],p[0])>0 && p[my].x>=p[i].x) ||
(multiply(p[i],p[my],p[0])<0 && p[my].x<=p[i].x))
lx=0;
ans=(p[i].y-p[0].y)*lx/2;
}
else
{
lx=p[my].x+(t[(i+1)/2].b*p[my].y+t[(i+1)/2].c)/t[(i+1)/2].a;
if((multiply(p[my],p[i],p[0])>0 && p[i].x>=p[my].x) ||
(multiply(p[my],p[i],p[0])<0 && p[i].x<=p[my].x))
lx=0;
ans=(p[my].y-p[0].y)*lx/2;
}
}
}
}
}
ans=fabs(ans);
}
printf("%.2lf\n",ans);
}
return 0;
}