一道模板题,倒是提醒了我还要加一加外面的边框
lf这玩意= =我竟然又忘了,连清打脸
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
//精度控制
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)<eps) return 0;
return x<0?-1:1;
}
//点
struct Point
{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
//向量
typedef Point Vector;
//点-点==向量
Vector operator-(Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
//向量+向量==向量 或 点+向量==点
Vector operator+(Vector A,Vector B)
{
return Vector(A.x+B.x,A.y+B.y);
}
//向量*实数==向量
Vector operator*(Vector A,double p)
{
return Vector(A.x*p,A.y*p);
}
//求向量长度
double Length(Vector v)
{
return sqrt(v.x*v.x+v.y*v.y);
}
//返回v逆时针旋转90度的单位向量
Vector Normal(Vector v)
{
double L=Length(v);
return Vector(-v.y/L, v.x/L);
}
//叉积
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
//直线
struct Line
{
Point p;
Vector v;
double ang;
Line(){}
Line(Point p,Vector v):p(p),v(v)
{
ang=atan2(v.y,v.x);
}
bool operator<(const Line &L)const
{
return ang<L.ang;
}
};
//判断p是否在直线L左边(在直线上不算)
bool OnLeft(Line L,Point p)
{
return Cross(L.v,p-L.p)>0;
}
//得到直线的交点
Point GetIntersection(Line a,Line b)
{
Vector u=a.p-b.p;
double t=Cross(b.v,u)/Cross(a.v,b.v);
return a.p+a.v*t;
}
//求直线集合L构成的半平面交集,如果存在是一个凸包
int HalfplaneIntersection(Line *L,int n,Point *poly)
{
//极角排序
sort(L,L+n);
int first=0,last=0;
Point *p=new Point[n];
Line *q=new Line[n];
q[0]=L[0];
for(int i=1;i<n;i++)
{
//删除尾部无效节点
while(first<last && !OnLeft(L[i],p[last-1])) last--;
//删除头部无效节点
while(first<last && !OnLeft(L[i],p[first])) first++;
//插入新直线
q[++last]=L[i];
//如果新插入的直线与last直线平行,需要删除最右边的那条
if(fabs(Cross(q[last].v,q[last-1].v))<eps)
{
last--;
if(OnLeft(q[last],L[i].p)) q[last]=L[i];
}
//新插入直线与上一条直线构成last-1交点
if(first<last) p[last-1]=GetIntersection(q[last-1],q[last]);
}
//同first直线排序尾部无效节点
while(first<last && !OnLeft(q[first],p[last-1])) last--;
//半平面不构成有界区域
if(last-first<=1 ) return 0;
//求首直线与尾直线交点
p[last]=GetIntersection(q[last],q[first]);
int m=0;
for(int i=first;i<=last;i++) poly[m++]=p[i];
return m;
}
//多边形面积
double PolygonArea(Point *p,int n)
{
double area=0;
for(int i=1;i<n-1;i++)
area += Cross(p[i]-p[0],p[i+1]-p[0]);
return fabs(area)/2;
}
const int N=20000+10;
Point p1,p2,Poly[N],pa,pb,pc,pd;
Line l[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y);
l[i]=Line(p1,p2-p1);
}
pa=Point(0,0);pb=Point(10000,0);pc=Point(10000,10000);pd=Point(0,10000);
l[n]=Line(pa,pb-pa);l[n+1]=Line(pb,pc-pb);l[n+2]=Line(pc,pd-pc);l[n+3]=Line(pd,pa-pd);
int m=HalfplaneIntersection(l,n+4,Poly);
if(!m)printf("0.0\n");
else{
double area=PolygonArea(Poly,m);
printf("%.1lf\n",area);
}
return 0;
}