1616
1717typedef Point < double > P ;
1818typedef array < P , 2 > Line ;
19- #define v (a ) (a[1] - a[0])
20- #define c (a ) (v(a).cross(a[0]))
21- pair < int , P > lineInter (Line a , Line b ) {
22- auto d = v (a ).cross (v (b ));
23- if (d == 0 ) return {- (c (a ) == c (b )), P (0 ,0 )};
24- else return {1 , (v (b )* c (a ) - v (a )* c (b ))/d };
25- }
19+ #define sp (a ) a[0], a[1]
20+ #define ang (a ) atan2((a[1] - a[0]).y, (a[1] - a[0]).x)
2621
27- #define ang (a ) atan2(v(a).y, v(a).x)
28- int sideOf (Line l , P p ) {return sideOf (l [0 ], l [1 ], p );}
2922vector < P > halfPlaneIntersection (vector < Line > vs ) {
3023 sort (all (vs ), [](auto a , auto b ) { return ang (a ) < ang (b );});
3124 vs .resize (unique (all (vs ), [](auto a , auto b ){ return ang (a ) == ang (b );}) - vs .begin ());
32- deque < Line > deq ({vs [0 ]});
33- deque < P > ans ;
25+ vector < Line > deq (sz (vs )+ 5 );
26+ vector < P > ans (sz (vs )+ 5 );
27+ int dh = 0 , dt = 1 , ah = 0 , at = 0 ;
28+ deq [0 ] = vs [0 ];
3429 for (int i = 1 ; i < sz (vs ); ++ i ) {
35- if (sgn (ang (vs [i ]) - ang (vs [i - 1 ])) == 0 ) continue ;
36- while (sz (ans ) && sideOf (vs [i ], ans .back ())< 0 )
37- ans .pop_back (), deq .pop_back ();
38- while (sz (ans ) && sideOf (vs [i ], ans .front ()) < 0 )
39- ans .pop_front (), deq .pop_front ();
40- ans .push_back (lineInter (deq .back (), vs [i ]).second );
41- deq .push_back (vs [i ]);
30+ if (ang (vs [i ]) - ang (vs [i - 1 ]) == 0 ) continue ;
31+ while (ah < at && sideOf (sp (vs [i ]), ans [at - 1 ])< 0 ) at -- , dt -- ;
32+ while (ah < at && sideOf (sp (vs [i ]), ans [ah ]) < 0 ) ah ++ , dh ++ ;
33+ ans [at ++ ] = lineInter (sp (deq [dt - 1 ]), sp (vs [i ])).second ;
34+ deq [dt ++ ] = vs [i ];
4235 }
43- while (sz (ans ) && sideOf (deq .front (), ans .back ()) < 0 )
44- ans .pop_back (), deq .pop_back ();
45- while (sz (ans ) && sideOf (deq .back (), ans .front ()) < 0 )
46- ans .pop_front (), deq .pop_front ();
47- if (sz (deq ) <= 2 ) return {};
48- ans .push_back (lineInter (deq .front (), deq .back ()).second );
49- return vector < P > (all (ans ));
36+ while (ah < at && sideOf (sp (deq [dh ]), ans [at - 1 ]) < 0 ) at -- , dt -- ;
37+ while (ah < at && sideOf (sp (deq [dt ]), ans [ah ]) < 0 ) ah ++ , dh ++ ;
38+ if (dt - dh <= 2 ) return {};
39+ ans [at ++ ] = lineInter (sp (deq [dh ]), sp (deq [dt - 1 ])).second ;
40+ return {ans .begin ()+ ah , ans .begin ()+ at };
5041}
0 commit comments