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