summaryrefslogtreecommitdiff
path: root/geometry/polygon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'geometry/polygon.cpp')
-rw-r--r--geometry/polygon.cpp150
1 files changed, 0 insertions, 150 deletions
diff --git a/geometry/polygon.cpp b/geometry/polygon.cpp
deleted file mode 100644
index e3ce33e..0000000
--- a/geometry/polygon.cpp
+++ /dev/null
@@ -1,150 +0,0 @@
-// Flächeninhalt eines Polygons (nicht selbstschneidend).
-// Punkte gegen den Uhrzeigersinn: positiv, sonst negativ.
-double area(const vector<pt>& poly) { //poly[0] == poly.back()
- double res = 0;
- for (int i = 0; i + 1 < sz(poly); i++)
- res += cross(poly[i], poly[i + 1]);
- return 0.5 * res;
-}
-
-// Anzahl drehungen einer Polyline um einen Punkt
-// p nicht auf rand und poly[0] == poly.back()
-// res != 0 or (res & 1) != 0 um inside zu prüfen bei
-// selbstschneidenden Polygonen (definitions Sache)
-ll windingNumber(pt p, const vector<pt>& poly) {
- ll res = 0;
- for (int i = 0; i + 1 < sz(poly); i++) {
- pt a = poly[i], b = poly[i + 1];
- if (real(a) > real(b)) swap(a, b);
- if (real(a) <= real(p) && real(p) < real(b) &&
- cross(p, a, b) < 0) {
- res += orientation(p, poly[i], poly[i + 1]);
- }}
- return res;
-}
-
-// Testet, ob ein Punkt im Polygon liegt (beliebige Polygone).
-// Ändere Zeile 32 falls rand zählt, poly[0] == poly.back()
-bool inside(pt p, const vector<pt>& poly) {
- bool in = false;
- for (int i = 0; i + 1 < sz(poly); i++) {
- pt a = poly[i], b = poly[i + 1];
- if (pointOnLineSegment(a, b, p)) return false;
- if (real(a) > real(b)) swap(a,b);
- if (real(a) <= real(p) && real(p) < real(b) &&
- cross(p, a, b) < 0) {
- in ^= 1;
- }}
- return in;
-}
-
-// convex hull without duplicates, h[0] != h.back()
-// apply comments if border counts as inside
-bool inside(pt p, const vector<pt>& hull) {
- int l = 0, r = sz(hull) - 1;
- if (cross(hull[0], hull[r], p) >= 0) return false; // > 0
- while (l + 1 < r) {
- int m = (l + r) / 2;
- if (cross(hull[0], hull[m], p) > 0) l = m; // >= 0
- else r = m;
- }
- return cross(hull[l], hull[r], p) > 0; // >= 0
-}
-
-void rotateMin(vector<pt>& hull) {
- auto mi = min_element(all(hull), [](const pt& a, const pt& b){
- return real(a) == real(b) ? imag(a) < imag(b)
- : real(a) < real(b);
- });
- rotate(hull.begin(), mi, hull.end());
-}
-
-// convex hulls without duplicates, h[0] != h.back()
-vector<pt> minkowski(vector<pt> ps, vector<pt> qs) {
- rotateMin(ps);
- rotateMin(qs);
- ps.push_back(ps[0]);
- qs.push_back(qs[0]);
- ps.push_back(ps[1]);
- qs.push_back(qs[1]);
- vector<pt> res;
- for (ll i = 0, j = 0; i + 2 < sz(ps) || j + 2 < sz(qs);) {
- res.push_back(ps[i] + qs[j]);
- auto c = cross(ps[i + 1] - ps[i], qs[j + 1] - qs[j]);
- if(c >= 0) i++;
- if(c <= 0) j++;
- }
- return res;
-}
-
-// convex hulls without duplicates, h[0] != h.back()
-double dist(const vector<pt>& ps, const vector<pt>& qs) {
- for (pt& q : qs) q *= -1;
- auto p = minkowski(ps, qs);
- p.push_back(p[0]);
- double res = 0.0;
- //bool intersect = true;
- for (ll i = 0; i + 1 < sz(p); i++) {
- //intersect &= cross(p[i], p[i+1] - p[i]) <= 0;
- res = max(res, cross(p[i], p[i+1]-p[i]) / abs(p[i+1]-p[i]));
- }
- return res;
-}
-
-bool left(pt of, pt p) {return cross(p, of) < 0 ||
- (cross(p, of) == 0 && dot(p, of) > 0);}
-
-// convex hulls without duplicates, hull[0] == hull.back() and
-// hull[0] must be a convex point (with angle < pi)
-// returns index of corner where dot(dir, corner) is maximized
-int extremal(const vector<pt>& hull, pt dir) {
- dir *= pt(0, 1);
- int l = 0, r = sz(hull) - 1;
- while (l + 1 < r) {
- int m = (l + r) / 2;
- pt dm = hull[m+1]-hull[m];
- pt dl = hull[l+1]-hull[l];
- if (left(dl, dir) != left(dl, dm)) {
- if (left(dl, dm)) l = m;
- else r = m;
- } else {
- if (cross(dir, dm) < 0) l = m;
- else r = m;
- }}
- return r;
-}
-
-// convex hulls without duplicates, hull[0] == hull.back() and
-// hull[0] must be a convex point (with angle < pi)
-// {} if no intersection
-// {x} if corner is only intersection
-// {a, b} segments (a,a+1) and (b,b+1) intersected (if only the
-// border is intersected corners a and b are the start and end)
-vector<int> intersect(const vector<pt>& hull, pt a, pt b) {
- int endA = extremal(hull, (a-b) * pt(0, 1));
- int endB = extremal(hull, (b-a) * pt(0, 1));
- // cross == 0 => line only intersects border
- if (cross(hull[endA], a, b) > 0 ||
- cross(hull[endB], a, b) < 0) return {};
-
- int n = sz(hull) - 1;
- vector<int> res;
- for (auto _ : {0, 1}) {
- int l = endA, r = endB;
- if (r < l) r += n;
- while (l + 1 < r) {
- int m = (l + r) / 2;
- if (cross(hull[m % n], a, b) <= 0 &&
- cross(hull[m % n], a, b) != hull(poly[endB], a, b))
- l = m;
- else r = m;
- }
- if (cross(hull[r % n], a, b) == 0) l++;
- res.push_back(l % n);
- swap(endA, endB);
- swap(a, b);
- }
- if (res[0] == res[1]) res.pop_back();
- return res;
-}
-