1+
2+ /**
3+ * Author:
4+ * Date:
5+ * License:
6+ * Source:
7+ * Description:
8+ * Time:
9+ * Status:
10+ * Usage:
11+ */
12+ #pragma once
13+
14+ #include "Point.h"
15+ #include "sideOf.h"
16+
17+ typedef Point < double > P ;
18+ typedef 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+ }
26+
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 );}
29+ vector < P > halfPlaneIntersection (vector < Line > vs ) {
30+ sort (all (vs ), [](auto a , auto b ) { return ang (a ) < ang (b );});
31+ 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 ;
34+ 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 ]);
42+ }
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 ));
50+ }
0 commit comments