Changes
2 changed files (+92/-5)
-
-
@@ -43,6 +43,11 @@ int cross(vec a, vec b) {return a.x * b.y - a.y * b.x; } double angle(point a, point o, point b) { vec oa = to_vec(o, a), ob = to_vec(o, b); return acos(dot(oa, ob) / sqrt(norm_sq(oa) * norm_sq(ob))); } bool ccw(point p, point q, point r) { return cross(to_vec(p, q), to_vec(p, r)) > 0; }
-
@@ -63,7 +68,7 @@ int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b); } line points_to_line(point p1, point p2) { line to_line(point p1, point p2) { int a = p2.y - p1.y, b = p1.x - p2.x, c = p1.y * p2.x - p1.x * p2.y; int d = gcd(gcd(abs(a), abs(b)), abs(c)); return { a / d, b / d, c / d };
-
@@ -92,16 +97,16 @@ struct seg {seg(point _p1, point _p2) : p1(_p1), p2(_p2) {} }; line seg_to_line(seg s) { return points_to_line(s.p1, s.p2); line to_line(seg s) { return to_line(s.p1, s.p2); } double point_to_seg(point p, seg s) { int a = norm_sq(to_vec(s.p1, s.p2)), b = norm_sq(to_vec(p, s.p1)), c = norm_sq(to_vec(p, s.p2)); if (a + b > c && a + c > b) return point_to_line(p, seg_to_line(s)); if (a + b > c && a + c > b) return point_to_line(p, to_line(s)); else return min(dist(p, s.p1), dist(p, s.p2)); } bool seg_isect(seg a, seg b) { return ccw(a.p1, a.p2, b.p1) * ccw(a.p1, a.p2, b.p2) <= 0 && ccw(b.p1, b.p2, a.p1) * ccw(b.p1, b.p2, a.p2) <= 0); } }
-
-
Geometry/polygons.cpp (new)
-
@@ -0,0 +1,82 @@#include <algorithm> #include <vector> #include <cmath> using namespace std; struct point { int x, y; point() { x = y = 0; } point(int _x, int _y) : x(_x), y(_y) {} bool operator < (point p) const { return (x == p.x && y < p.y) || x < p.x; } bool operator == (point p) const { return x == p.x && y == p.y; } }; double dist(point& p1, point& p2) { return hypot(p1.x - p2.x, p1.y - p2.y); } struct vec { int x, y; vec(int _x, int _y) : x(_x), y(_y) {} }; vec to_vec(point a, point b) { return vec(b.x - a.x, b.y - a.y); } int dot(vec a, vec b) { return (a.x * b.x + a.y * b.y); } int norm_sq(vec v) { return v.x * v.x + v.y * v.y; } int cross(vec a, vec b) { return a.x * b.y - a.y * b.x; } bool ccw(point p, point q, point r) { return cross(to_vec(p, q), to_vec(p, r)) > 0; } double angle(point a, point o, point b) { vec oa = to_vec(o, a), ob = to_vec(o, b); return acos(dot(oa, ob) / (sqrt(norm_sq(oa)) * sqrt(norm_sq(ob)))); } bool in_polygon(point pt, const vector<point>& P) { double sum = 0; for (int i = 0; i < P.size() - 1; i++) { if (pt == P[i]) return true; if (ccw(pt, P[i], P[i + 1])) sum += angle(P[i], pt, P[i + 1]); else sum -= angle(P[i], pt, P[i + 1]); } return fabs(sum) > acos(-1.0); } double area(const vector<point>& P) { int res = 0; for (int i = 0; i < (int)P.size() - 1; i++) res += (P[i].x * P[i + 1].y - P[i + 1].x * P[i].y); return res / 2.0; } vector<point> convex_hull(vector<point>& P) { int n = P.size(), k = 0; vector<point> H(2 * n); sort(P.begin(), P.end()); for (int i = 0; i < n; i++) { while (k >= 2 && ccw(H[k - 2], H[k - 1], P[i]) <= 0) k--; H[k++] = P[i]; } for (int i = n - 2, t = k + 1; i >= 0; i--) { while (k >= t && ccw(H[k - 2], H[k - 1], P[i]) <= 0) k--; H[k++] = P[i]; } H.resize(k); return H; }
-