今日未AC,来日再战,头脑混沌。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps = 1e-8;
int dcmp( double x )
{
if( fabs(x)<eps)
return 0;
return x < 0 ? -1: 1;
}
//================= 点结构 ===============
struct pnode
{
double x,y;
pnode( double a=0.0,double b=0.0):x(a),y(b){}
// X乘重载
double operator ^ (const pnode &b)const
{
return x*b.y - b.x*y;
}
pnode operator - ( const pnode &b)const
{
return pnode( x-b.x, y-b.y);
}
pnode operator * (const double p)const
{
return pnode( x*p, y*p );
}
pnode operator + (const pnode&b)const
{
return pnode( x+b.x, y+b.y );
}
bool operator == (const pnode&b)const
{
return dcmp( x-b.x )== 0 && dcmp( y-b.y )==0;
}
bool operator < (const pnode&b)const
{
return x < b.x || ( dcmp( x-b.x )==0 && y<b.y );
}
bool operator > (const pnode&b)const
{
return x > b.x || ( dcmp( x-b.x )==0 && y>b.y );
}
};
//================ 线结构 ==============
typedef pnode myvec;
struct pline
{
pnode st,ed;//st:起始点 ed:终点
myvec vec;//向量
pline(){}
pline(pnode a,pnode b):st(a),ed(b)
{
vec = pnode(b-a);
}
void pread()
{
scanf("%lf %lf %lf %lf",&st.x,&st.y,&ed.x,&ed.y);
if( ed.y > st.y)
swap(st,ed);
vec = pnode(ed-st);
}
};
double cross( pnode p0,pnode p1,pnode p2)
{
return (p1-p0) ^ (p2-p0);
}
double cross(pline a,pline b)
{
return (a.ed-a.st)^(b.ed-b.st);
}
/*
点乘:
dot(v,w) == 二者长度乘积再乘上他们夹角的余弦
夹角:从 v 到 w 逆时针旋转的角
*/
double dot( myvec v,myvec w)
{
return v.x*w.x + v.y*w.y;
}
bool seg_inter_seg(pline a,pline b)
{
return
max( a.st.x, a.ed.x) >= min( b.st.x, b.ed.x)
&&
max( b.st.x, b.ed.x) >= min( a.st.x, a.ed.x)
&&
max( a.st.y, a.ed.y) >= min( b.st.y, b.ed.y)
&&
max( b.st.y, b.ed.y) >= min( a.st.y, a.ed.y)
&&//以上端点判断
dcmp(cross( a.st, a.ed, b.st ))*dcmp(cross( a.st, a.ed, b.ed ))<=0
&& dcmp(cross( b.st, b.ed, a.st ))*dcmp(cross( b.st, b.ed, a.ed ))<=0;
}
pnode get_line_inter_point(pline v,pline w)
{
pline u (w.st,v.st);
double t = cross( w,u )/cross(v,w);
return v.st + (v.ed-v.st) * t;
}
bool seg_inter_line(pline line,pline seg)
{
return ( dcmp( cross( seg.st,line.st,line.ed ) ) * dcmp( cross( seg.ed,line.st,line.ed) ) )<=0;
}
int check(pline a,pline b,pnode &p1,pnode &p2)
{
pnode getit;
pline ay (a.st,pnode(a.st.x+100,a.st.y));
pline by (b.st,pnode(b.st.x+100,a.st.y));
if( seg_inter_line(ay,b))
{
pline ax(a.st,pnode(a.st.x,10000 ));
if( seg_inter_seg(ax,b))
return 0;
p1 = get_line_inter_point(ay,b);
p2 = a.st;
return 1;
}
if( seg_inter_line(by,a))
{
pline bx(b.st,pnode(b.st.x,10000 ));
if( seg_inter_seg(bx,a))
return 0;
p1 = get_line_inter_point(by,a);
p2 = b.st;
return 1;
}
return 0;
}
pline a,b;
pline yl (pnode(0,0),pnode(0,100));
int main()
{
int cas;
scanf("%d",&cas);
while( cas-- )
{
a.pread();
b.pread();
if( dcmp ( cross(a,b)) == 0 || dcmp(dot(yl.vec,a.vec))==0 || dcmp(dot(yl.vec,b.vec))==0 )
{
puts("0.00");
//puts("1");
continue;
}
pnode p = get_line_inter_point(a,b),p1,p2;
int s = check(a,b,p1,p2);
if( s==0 )
{
puts("0.00");
//puts("2");
continue;
}
double area = fabs ( cross(p,p1,p2)*0.5 );
printf("%0.2f\n",area);
}
return 0;
}