#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; #define N 50005 const double eps=1e-8; int dcmp(double x) { if (x<=eps&&x>=-eps) return 0; return (x>0)?1:-1; } struct Vector { double x,y; Vector(double X=0,double Y=0){ x=X,y=Y; } }; typedef Vector Point; struct Line { Point p; Vector v; double ang; Line(Point P=Point(0,0),Vector V=Vector(0,0)) { p=P,v=V; ang=atan2(v.y,v.x); } bool operator < (const Line &a) const { return ang<a.ang; } }; Vector operator + (Vector a,Vector 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 b) {return Vector(a.x*b,a.y*b);} int n,l,r,m,cnt; double ans; Line L[N],q[N]; Point p[N],poly[N]; double Cross(Vector a,Vector b) { return a.x*b.y-a.y*b.x; } Point GLI(Point P,Vector v,Point Q,Vector w) { Vector u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t; } bool Onleft(Line m,Point P) { Vector w=P-m.p; return dcmp(Cross(m.v,w))>=0; } void halfp(){ sort(L+1,L+n+1); cnt=0; q[l=r=1]=L[1]; for (int i=2;i<=n;++i) { while (l<r&&!Onleft(L[i],p[r-1])) --r; while (l<r&&!Onleft(L[i],p[l])) ++l; q[++r]=L[i]; if (dcmp(Cross(q[r].v,q[r-1].v))==0) { --r; if (Onleft(q[r],L[i].p)) q[r]=L[i]; } if (l<r) p[r-1]=GLI(q[r-1].p,q[r-1].v,q[r].p,q[r].v); } while (l<r&&!Onleft(q[l],p[r-1])) --r; if (r-l<=1) return; p[r]=GLI(q[r].p,q[r].v,q[l].p,q[l].v); for (int i=l;i<=r;++i) poly[++cnt]=p[i]; } double Area() { double ans=0; for (int i=2;i<cnt;++i) ans+=Cross(poly[i]-poly[1],poly[i+1]-poly[1]); return fabs(ans/2); } int main() { scanf("%d",&n); // 输入点的个数 for (int i=1;i<=n;++i) { Point P,Q;double a,b,c,d; // 输入四个点的坐标 x1,y1,x2,y2 scanf("%lf%lf%lf%lf",&a,&b,&c,&d); P=Point(a,b);Q=Point(c,d); // 得到点 L[i]=Line(P,Q-P); // 通过一个点和线得到 直线 } // 开始需要设置一个无限大的区域 L[++n]=Line(Point(0,10000),Vector(0,-10000)); L[++n]=Line(Point(0,0),Vector(10000,0)); L[++n]=Line(Point(10000,0),Vector(0,10000)); L[++n]=Line(Point(10000,10000),Vector(-10000,0)); halfp(); printf("%.1lf\n",Area()); return 0; }