# 半平面交

  1 #include <bits/stdc++.h>
2 using namespace std;
3 #define DB double
4 const int maxn=100005;
5 const DB pi=acos(-1);
6 const DB eps=1e-6;
7 int n,t; DB ans;
8 struct N{
9     DB x,y;
10     N(DB a=0,DB b=0){x=a,y=b;}
11 }c[maxn];
12 struct L{
13     N a,b; double f;
14     L(N p=N(),N q=N()){
15         a=p,b=q; f=atan2(b.y-a.y,b.x-a.x);
16     }
17 }a[maxn],b[maxn];
18 N operator+(N a,N b){
19     return N(a.x+b.x,a.y+b.y);
20 }
21 N operator-(N a,N b){
22     return N(a.x-b.x,a.y-b.y);
23 }
24 DB operator*(N a,N b){
25     return a.x*b.y-a.y*b.x;
26 }
27 DB dot(N a,N b){
28     return a.x*b.x+a.y*b.y;
29 }
30 DB sqr(DB a){return a*a;}
31 DB dis(N a,N b){
32     return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
33 }
34 DB abs(N a){//模
35     return sqrt(a.x*a.x+a.y*a.y);
36 }
37 DB COS(N a,N b){//夹角[0,pi]的cos
38     return dot(a,b)/abs(a)/abs(b);
39 }
40 DB SIN(N a,N b){//夹角sin
41     return fabs(a*b)/abs(a)/abs(b);
42 }
43 L go(L s,DB m){//垂直左移m
44     N c=N(-sin(s.f)*m,cos(s.f)*m);
45     s.a=s.a+c; s.b=s.b+c; return s;
46 }
47 bool cmpL(L a,L b){
48     return fabs(a.f-b.f)>eps?a.f<b.f:(a.b-a.a)*(b.b-a.a)<-eps;//lefter
49 }
50 bool ON(N p,L e){//点在线段上
51     return fabs((e.a-p)*(e.b-p))<eps
52     &&(e.a.x-p.x)*(e.b.x-p.x)<eps
53     &&(e.a.y-p.y)*(e.b.y-p.y)<eps;
54 }
55 N inter(L a,L b){//如果f相同,回inf或nan
56     DB k1,k2,t;
57     k1=(b.b-a.a)*(a.b-a.a);
58     k2=(a.b-a.a)*(b.a-a.a);
59     t=k1/(k1+k2);
60     return N(b.b.x+(b.a.x-b.b.x)*t,b.b.y+(b.a.y-b.b.y)*t);
61 }
62 bool jud(L a,L b,L t){
63     N p=inter(a,b);
64     return (t.b-t.a)*(p-t.a)<eps;
65 }
66 void hpi(){
67     //anticlockwise
68     //保留L.a->L.b的左半平面
69     sort(a+1,a+n+1,cmpL);
70     t=0;
71     for (int i=1;i<=n;++i)
72     if (i==1||fabs(a[i].f-a[t].f)>eps) a[++t]=a[i];
73     n=t;
74     for (int i=1;i<n;++i)
75         if (a[i+1].f-a[i].f>=pi-eps){
76             if (fabs(a[i+1].f-a[i].f-pi)<eps&&(a[i+1].b-a[i].a)*(a[i].b-a[i].a)>-eps){
77                 printf("%.4lf\n",0.0); exit(0);
78             }
79             puts("-1"); exit(0);
80         }
81     if (a[1].f+2*pi-a[n].f>=pi-eps){
82         if (fabs(a[1].f+2*pi-a[n].f-pi)<eps&&(a[1].b-a[n].a)*(a[n].b-a[n].a)>-eps){
83             printf("%.4lf\n",0.0); exit(0);
84         }
85         puts("-1"); exit(0);
86     }
87     int l=1,r=0; t=0;
88     for (int i=1;i<=n;++i)
89     if (i==1||fabs(a[i].f-a[t].f)>eps) a[++t]=a[i];
90     for (int i=1;i<=t;++i){
91         while (l<r&&jud(b[r-1],b[r],a[i])) --r;
92         while (l<r&&jud(b[l+1],b[l],a[i])) ++l;
93         b[++r]=a[i];
94     }
95     while (l<r&&jud(b[r-1],b[r],b[l])) --r;
96     while (l<r&&jud(b[l+1],b[l],b[r])) ++l;
97     b[l-1]=b[r]; t=0;
98     for (int i=l;i<=r;++i) c[++t]=inter(b[i-1],b[i]);
99 }
100 int main(){
101     scanf("%d",&n);
102     for (int i=1;i<=n;++i){
103         DB A,B,C;       //Ax+By+C>=0
104         scanf("%lf%lf%lf",&A,&B,&C);
105         if (fabs(B)>eps){
106             if (B>0) a[i]=L(N(0,-C/B),N(1,(-A-C)/B));
107                 else a[i]=L(N(1,(-A-C)/B),N(0,-C/B));
108         }else{
109             if (A>0) a[i]=L(N(-C/A,1),N(-C/A,0));
110                 else a[i]=L(N(-C/A,0),N(-C/A,1));
111         }
112     }
113     hpi();
114
115     ans=0;
116     for (int i=2;i<t;++i) ans+=(c[i+1]-c[1])*(c[i]-c[1]);
117     printf("%.4lf\n",-ans/2);
118     return 0;
119 }

posted @ 2017-12-19 10:06  cyz666  阅读(139)  评论(0编辑  收藏