[Formwork] Half plane intersection

practice

Consider using rays (a point and a vector) to represent the half plane on its left

Then we can first sort by the included angle with the positive half axis of the x-axis (which can be realized by atan2 (y, x)), and then use the two end queue to maintain the rays currently in transit

The reason for using a double ended queue is that when a new half plane is inserted, the head and tail of the team may be popped out, and it should be noted that the tail of the team should be popped first and then the head

At the end, the head of the team will play some of the tail

Example

Luogu4196 convex polygon
 one #include<bits/stdc++.h> two  #define pa pair<int,int> three  #define CLR(a,x) memset(a,x,sizeof(a)) four  #define MP make_pair five  #define fi first six  #define se second seven  using  namespace std; eight typedef long  long ll; nine typedef unsigned long  long ull; ten typedef unsigned int ui; eleven typedef long  double ld; twelve  const  int maxl= two thousand three hundred and thirty-three ,maxn= twelve ,maxm= fifty-five ; thirteen  const ld eps=1e- nine ; fourteen 
 fifteen inline char gc(){ sixteen      return getchar(); seventeen      static  const  int maxs= one << sixteen ; static  char buf[maxs],*p1=buf,*p2= buf; eighteen      return p1==p2&&(p2=(p1=buf)+fread(buf, one ,maxs,stdin),p1==p2)? EOF:*p1++ ; nineteen  } twenty  inline ll rd(){ twenty-one ll x= zero ; char c=gc(); bool neg= zero ; twenty-two      while (c< ' zero ' ||c> ' nine ' ){ if (c== ' - ' ) neg= one ; c= gc();} twenty-three      while (c>= ' zero ' &&c<= ' nine ' ) x=(x<< one )+(x<< three )+c- ' zero ' ,c= gc(); twenty-four      return neg? (~x+ one ):x; twenty-five  } twenty-six 
 twenty-seven  struct Node{ twenty-eight  ld x,y; twenty-nine Node(ld _x= zero ,ld _y= zero ){x=_x,y= _y;} thirty  }p[maxn][maxm],it[maxl]; thirty-one  struct Line{ thirty-two  Node x,y; thirty-three Line(Node _x= zero ,Node _y= zero ){x=_x,y= _y;} thirty-four  }l[maxl]; thirty-five  int N,M[maxn],cnt; thirty-six  int hd,tl,q[maxl]; thirty-seven 
 thirty-eight inline ld operator ^( const Node a, const Node b){ return a.x*b.y-a.y* b.x;} thirty-nine inline Node operator +( const Node a, const Node b){ return Node(a.x+b.x,a.y+ b.y);} forty inline Node operator -( const Node a, const Node b){ return Node(a.x-b.x,a.y- b.y);} forty-one inline Node operator *( const Node a, const ld b){ return Node(a.x*b,a.y* b);} forty-two inline ld myabs( const ld x){ return x> zero ? x:- x;} forty-three inline Node inter( const Line a, const Line b){ forty-four ld k1=(a.y-a.x)^(b.y-a.x),k2=(b.x-a.x)^(a.y- a.x); forty-five      return b.x+(b.y-b.x)*(k2/(k1+ k2)); forty-six  } forty-seven inline bool onright( const Line a, const Node b){ return ((b-a.x)^(a.y-a.x))>=- eps;} forty-eight inline ld slope(Line a){ return atan2((a.y-a.x).y,(a.y- a.x).x);} forty-nine 
 fifty inline bool cmp(Line a,Line b){ fifty-one ld x=slope(a),y= slope(b); fifty-two      return (myabs(x-y)<eps)? (!onright(b,a.x)):(x< y); fifty-three  } fifty-four 
 fifty-five  inline ld solve(){ fifty-six sort(l+ one ,l+cnt+ one ,cmp); fifty-seven hd= one ,tl= zero ; fifty-eight      for ( int i= one ; i<=cnt; i++ ){ fifty-nine          // printf("~%Lf %Lf\n",(l[i].y-l[i].x).x,(l[i].y-l[i].x).y);
 sixty          if (i> one &&myabs(slope(l[i])-slope(l[i- one ]))<eps) continue ; sixty-one          while (hd<tl&&onright(l[i],inter(l[q[tl]],l[q[tl- one ]]))) tl-- ; sixty-two          while (hd<tl&&onright(l[i],inter(l[q[hd]],l[q[hd+ one ]]))) hd++ ; sixty-three q[++tl]= i; sixty-four  } sixty-five      while (hd<tl&&onright(l[q[hd]],inter(l[q[tl]],l[q[tl- one ]]))) tl-- ; sixty-six      // while(hd<tl&&onright(l[q[tl]],inter(l[q[hd]],l[q[hd+1]]))) hd++; sixty-seven      // for(int i=hd;i<=tl;i++) printf("~%Lf %Lf %Lf %Lf\n",l[q[i]].x.x,l[q[i]].x.y,l[q[i]].y.x,l[q[i]].y.y);
 sixty-eight      if (hd+ two >tl) return  zero ; sixty-nine ld re= zero ; seventy q[tl+ one ]=q[hd]; int n= zero ; seventy-one      for ( int i=hd; i<=tl; i++) it[++n]=inter(l[q[i]],l[q[i+ one ]]); seventy-two      for ( int i= two ; i<n; i++) re+=myabs((it[i]-it[ one ])^(it[i+ one ]-it[ one ])); seventy-three      return re/ two ; seventy-four  } seventy-five 
 seventy-six  int main(){ seventy-seven      // freopen("","r",stdin);
 seventy-eight N= rd(); seventy-nine      for ( int i= one ; i<=N; i++ ){ eighty M[i]= rd(); eighty-one          for ( int j= zero ; j<M[i]; j++ ) eighty-two p[i][j].x=rd(),p[i][j].y= rd(); eighty-three          for ( int j= zero ; j<M[i]; j++ ){ eighty-four l[++cnt]=Line(p[i][j],p[i][(j+ one )% M[i]]); eighty-five  } eighty-six  } eighty-seven printf( " %.3Lf\n " ,solve()); eighty-eight      return  zero ; eighty-nine }

 

posted @ 2019-06-20 14:15   Ressed   Reading( one hundred and ninety Comments( zero edit   Collection   report