1- // polygon intersecting left side of hps
2- struct hp : public ln {
3- ld angle ;
4- hp (){}
5- hp (pt a , pt b ){p = a ; pq = b - a ; angle = atan2 (pq .y ,pq .x );}
6- bool operator < (hp b )const {return angle < b .angle ;}
7- bool out (pt q ){return pq %(q - p )< - eps ;}
1+ typedef long double ld ;
2+ const ld eps = 1e-10 , inf = 1e50 ;
3+ struct pt { // for 3D add z coordinate
4+ ld x ,y ;
5+ pt (){}
6+ pt (ld x , ld y ):x (x ),y (y ){}
7+
8+ pt operator + (pt p ){return pt (x + p .x ,y + p .y );}
9+ pt operator - (pt p ){return pt (x - p .x ,y - p .y );}
10+ pt operator * (ld t ){return pt (x * t ,y * t );}
11+ pt operator /(ld t ){return pt (x /t ,y /t );}
12+ ld operator * (pt p ){return x * p .x + y * p .y ;}
13+ ld operator %(pt p ){return x * p .y - y * p .x ;}
14+
15+ ld norm2 (){return * this * * this ;}
16+ ld norm (){return sqrt (norm2 ());}
17+ pt unit (){return * this /norm ();}
18+ };
19+ struct ln {
20+ pt p ,pq ;
21+ ln (){}
22+ ln (pt p , pt q ):p (p ),pq (q - p ){}
23+ bool operator /(ln l ){return abs (pq .unit ()%l .pq .unit ()) <= eps ;}
24+ pt operator ^(ln l ){ // intersection
25+ if (* this /l ) return pt (inf ,inf );
26+ pt r = l .p + l .pq * ((p - l .p )%pq / (l .pq %pq ));
27+ return r ;
28+ }
829};
930
10- vector < pt > intersect (vector < hp > b ){
11- vector < pt > bx = {{inf ,inf },{- inf ,inf },{- inf ,- inf },{inf ,- inf }};
12- forn (i ,4 ) b .pb (hp (bx [i ],bx [(i + 1 )%4 ]));
13- sort (all (b ));
14- int n = sz (b ), q = 1 , h = 0 ;
15- vector < hp > c (sz (b )+ 10 );
16- forn (i ,n ){
17- while (q < h && b [i ].out (c [h ]^c [h - 1 ])) h -- ;
18- while (q < h && b [i ].out (c [q ]^c [q + 1 ])) q ++ ;
19- c [++ h ]= b [i ];
20- if (q < h && abs (c [h ].pq %c [h - 1 ].pq )< eps ){
21- if (c [h ].pq * c [h - 1 ].pq <=0 ) return {};
22- h -- ;
23- if (b [i ].out (c [h ].p )) c [h ]= b [i ];
24- }
25- }
26- while (q < h - 1 && c [q ].out (c [h ]^c [h - 1 ]))h -- ;
27- while (q < h - 1 && c [h ].out (c [q ]^c [q + 1 ]))q ++ ;
28- if (h - q <=1 )return {};
29- c [h + 1 ]= c [q ];
30- vector < pt > s ;
31- fore (i ,q ,h ) s .pb (c [i ]^c [i + 1 ]);
32- return s ;
33- }
31+ // polygon intersecting left side of halfplanes (CCW order)
32+ struct hp :public ln {
33+ ld angle ;
34+ hp (){}
35+ hp (pt a , pt b ){p = a ; pq = b - a ; angle = atan2 (pq .y , pq .x );}
36+ bool operator < (hp b )const {return angle < b .angle ;}
37+ bool out (pt q ){return pq %(q - p ) < - eps ;}
38+ };
39+ vector < pt > intersect (vector < hp > & b ){
40+ vector < pt > bx = {{inf ,inf }, {- inf ,inf }, {- inf ,- inf }, {inf ,- inf }};
41+ forn (i ,4 ) b .pb (hp (bx [i ],bx [(i + 1 )%4 ]));
42+ sort (all (b ));
43+ int n = sz (b ), q = 1 , h = 0 ;
44+ vector < hp > c (sz (b )+ 10 );
45+ forn (i ,n ){
46+ while (q < h && b [i ].out (c [h ]^c [h - 1 ])) h -- ;
47+ while (q < h && b [i ].out (c [q ]^c [q + 1 ])) q ++ ;
48+ c [++ h ] = b [i ];
49+ if (q < h && abs (c [h ].pq %c [h - 1 ].pq ) < eps ){
50+ if (c [h ].pq * c [h - 1 ].pq <= 0 ) return {};
51+ h -- ;
52+ if (b [i ].out (c [h ].p )) c [h ]= b [i ];
53+ }
54+ }
55+ while (q < h - 1 && c [q ].out (c [h ]^c [h - 1 ])) h -- ;
56+ while (q < h - 1 && c [h ].out (c [q ]^c [q + 1 ])) q ++ ;
57+ if (h - q <= 1 ) return {};
58+ c [h + 1 ] = c [q ];
59+ vector < pt > s ;
60+ fore (i ,q ,h ) s .pb (c [i ]^c [i + 1 ]);
61+ return s ;
62+ }
0 commit comments