-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeometry.cpp
More file actions
134 lines (116 loc) · 3.22 KB
/
geometry.cpp
File metadata and controls
134 lines (116 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "geometry.h"
#include <complex>
#include <vector>
#include <utility>
#define rep2(i,m,n) for(int i=(int)(m);i<(int)(n);i++)
#define rep(i,n) rep2(i,0,n)
#define squere(x) ((x)*(x))
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
static int dx[4] = {-1,0,1,0};
static int dy[4] = {0,1,0,-1};
bool operator < (const Pt& a, const Pt& b) {
return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
Real cross(const Pt& a, const Pt& b) {
return imag(conj(a)*b);
}
Real dot(const Pt& a, const Pt& b) {
return real(conj(a)*b);
}
bool near(const Pt& p, const Pt& q){return abs(p - q) < EPS;}
LPposit ccw(const Pt& p, const Pt& q, const Pt& r) {
Real c = cross(q-p,r-p);
if (c < -EPS) return P_CW;
if (c > EPS) return P_CCW;
if (dot(q - p, r - p) < -EPS) return P_CD;
if (dot(p - q, r - q) < -EPS) return P_D;
return P_OS;
}
// 線分の長さ
Real Sabs(const Line& l) {return abs(l.first - l.second); }
// 直線と点の距離
Real LPdist(const Line& l, const Pt& p) {return abs(cross(l.second-l.first,p-l.first)) / Sabs(l); }
// 点と線分の距離
Real SPdist(Line l, Pt p) {
Real a = abs(l.first - p);
Real b = abs(l.second - p);
Real c = Sabs(l);
if (b * b + c * c > a * a && a * a + c * c > b * b){
return LPdist(l, p);
}
return min(a, b);
}
// 線分交差判定
bool crossS(const Line& p, const Line& q){
return
ccw(p.first, p.second, q.first) * ccw(p.first, p.second, q.second) <= 0 &&
ccw(q.first, q.second, p.first) * ccw(q.first, q.second, p.second) <= 0;
}
// 直線の交差判定
Pt intersect(const Line& p, const Line& q) {
Pt vp = p.second - p.first;
Pt vq = q.second - q.first;
Pt c(cross(vp, p.first), cross(vq, q.first));
return Pt(cross(c, Pt(vp.real(), vq.real())), cross(c, Pt(vp.imag(), vq.imag()))) / cross(vp, vq);
}
// 直線の交点
// tested: AOJ 2003
Pt line_line_intersect(const Line &p, const Line &q)
{
Pt b = q.second-q.first;
Real d1 = abs(cross(b, p.first-q.first));
Real d2 = abs(cross(b, p.second-q.first));
Real t = d1 / (d1 + d2);
return p.first+(p.second-p.first)*t;
}
// 円と直線の交点
vector<Pt> circle_line_intersect(Line l,Cir c){
vector<Pt> ret;
Real di = LPdist(l,c.p);
Real r=c.r;
if(di+EPS > r) return ret;
Pt v=(l.second-l.first);
v/=abs(v);
Pt rv=v*Pt(0,1);
rv*=di;
if(LPdist(l,c.p+rv) > di+EPS) rv = -rv;
v*=sqrt(r*r-di*di);
ret.push_back(c.p+rv-v);
ret.push_back(c.p+rv+v);
return ret;
}
bool eq(Real l, Real r)
{
return (abs(l-r) < EPS);
}
int contains(const Poly& P, const Pt& p) {
bool in = false;
int n = P.size();
for (int i = 0; i < n; ++i) {
Pt a = P[i] - p, b = P[(i+1)%n] - p;
if (imag(a) > imag(b)) swap(a, b);
if (imag(a) <= 0 && 0 < imag(b))
if (cross(a, b) < 0) in = !in;
if (cross(a, b) == 0 && dot(a, b) <= 0) return GEOMETRY_ON;
}
return in ? GEOMETRY_IN : GEOMETRY_OUT;
}
Pt normalize(const Pt& p) {
return p/abs(p);
}
Pt reflection(const Pt& v, const Line& l) {
Pt p = l.first-l.second;
p = normalize(p);
Pt vp = p*dot(p, v);
Pt vn = v-vp;
return vp-vn;
}
Pt vertical(const Line& l) {
Pt p = l.first - l.second;
return Pt(-imag(p), real(p));
}