Skip to content

Commit 8207034

Browse files
authored
Merge pull request #4 from scanof/geo
Update halfplane.h
2 parents b74a8d4 + a9db6bd commit 8207034

File tree

1 file changed

+60
-31
lines changed

1 file changed

+60
-31
lines changed

code/geometry/halfplane.h

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,62 @@
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

Comments
 (0)