一开始真以为是水题 然后WA了一天
两线段所在直线的关系有平行与相交
首先平行绝对不可以 去掉平行时顺带去掉了重叠或部分重叠这一情况
若相交且可以盛水 则四个端点中必有两个在交点上方
分类讨论
1. 两点在交点异侧
这种情况下必然可以盛水 直接计算(详见代码)
2. 两点在交点同侧
这时可能会存在上方的线段l1(p0p1)将下方的线段l2(p0p2)完全盖住而无法盛水的情况 必须注意
这种情况通过比较 1与l2的斜率 及 p1与p2的端点 即可判别
还有 实在过不了记得把答案加个eps 坑。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define eps 1e-8
struct node
{
double x;
double y;
};
double cal(node a,node b,node c)//AB X AC
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
double getx(double y,node p1,node p2)
{
return (p2.x-p1.x)*(y-p2.y)/(p2.y-p1.y)+p2.x;
}
double getk(node p1,node p2)
{
return (p2.y-p1.y)/(p2.x-p1.x);
}
bool judge(node a,node b,node c,node d)
{
if(cal(a,b,c)*cal(a,b,d)<eps&&cal(c,d,a)*cal(c,d,b)<eps&&getk(a,b)!=getk(c,d))
{
return true;
}
else return false;
}
node getpoint(node a,node b,node c,node d)
{
node res;
double a1,b1,c1,a2,b2,c2;
a1=a.y-b.y,b1=b.x-a.x,c1=a.x*b.y-b.x*a.y;
a2=c.y-d.y,b2=d.x-c.x,c2=c.x*d.y-d.x*c.y;
res.x=(b1*c2-b2*c1)/(a1*b2-a2*b1);
res.y=-(a1*c2-a2*c1)/(a1*b2-a2*b1);
return res;
}
void solve(node p0,node p1,node p2)
{
node tp;
double ans,tx;
ans=0;
if(fabs(p0.x-p1.x)<eps||fabs(p0.x-p2.x)<eps||(p0.x-p1.x>eps&&p0.x-p2.x<eps)||(p0.x-p1.x<eps&&p0.x-p2.x>eps))//102 201
{
if(p2.y-p1.y>eps)
{
tx=getx(p1.y,p0,p2);
ans=fabs(p1.x-tx)*(p1.y-p0.y)/2;
}
else
{
tx=getx(p2.y,p0,p1);
ans=fabs(p2.x-tx)*(p2.y-p0.y)/2;
}
}
else if(p0.x-p1.x<eps&&p0.x-p2.x<eps)//012
{
if(p2.y-p1.y>eps)
{
if(getk(p0,p1)-getk(p0,p2)>eps||(getk(p0,p1)-getk(p0,p2)<eps&&p1.x-p2.x>0))
{
tx=getx(p1.y,p0,p2);
ans=fabs(p1.x-tx)*(p1.y-p0.y)/2;
}
}
else
{
if(getk(p0,p2)-getk(p0,p1)>eps||(getk(p0,p2)-getk(p0,p1)<eps&&p2.x-p1.x>0))
{
tx=getx(p2.y,p0,p1);
ans=fabs(p2.x-tx)*(p2.y-p0.y)/2;
}
}
}
else if(p0.x-p1.x>eps&&p0.x-p2.x>eps)//120
{
if(p2.y-p1.y>eps)
{
if(getk(p0,p1)-getk(p0,p2)<eps||(getk(p0,p1)-getk(p0,p2)>eps&&p1.x-p2.x<0))
{
tx=getx(p1.y,p0,p2);
ans=fabs(p1.x-tx)*(p1.y-p0.y)/2;
}
}
else
{
if(getk(p0,p2)-getk(p0,p1)<eps||(getk(p0,p2)-getk(p0,p1)>eps&&p2.x-p1.x<0))
{
tx=getx(p2.y,p0,p1);
ans=fabs(p2.x-tx)*(p2.y-p0.y)/2;
}
}
}
printf("%.2f\n",ans+eps);
return;
}
int main()
{
node pre[2];
node p0,p1,p2,p3,p4;
int t,i;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y,&p3.x,&p3.y,&p4.x,&p4.y);
if(!judge(p1,p2,p3,p4))
{
printf("0.00\n");
continue;
}
p0=getpoint(p1,p2,p3,p4);
i=0;
if(p1.y-p0.y>eps) pre[i++]=p1;
if(p2.y-p0.y>eps) pre[i++]=p2;
if(p3.y-p0.y>eps) pre[i++]=p3;
if(p4.y-p0.y>eps) pre[i++]=p4;
if(i<2)
{
printf("0.00\n");
continue;
}
solve(p0,pre[0],pre[1]);
}
return 0;
}