16
16
17
17
typedef Point < double > P ;
18
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
- }
19
+ #define sp (a ) a[0], a[1]
20
+ #define ang (a ) atan2((a[1] - a[0]).y, (a[1] - a[0]).x)
26
21
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
22
vector < P > halfPlaneIntersection (vector < Line > vs ) {
30
23
sort (all (vs ), [](auto a , auto b ) { return ang (a ) < ang (b );});
31
24
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 ];
34
29
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 ];
42
35
}
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 };
50
41
}
0 commit comments