From f8902de5e67fa3184710dbc1e56c77c795026241 Mon Sep 17 00:00:00 2001 From: szdytom Date: Fri, 26 May 2023 17:01:21 +0800 Subject: [PATCH] [feat] 2d lib --- 2d.hpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 2d.hpp diff --git a/2d.hpp b/2d.hpp new file mode 100644 index 0000000..9ec23ae --- /dev/null +++ b/2d.hpp @@ -0,0 +1,112 @@ +#ifndef header_2d +#define header_2d + +#include +#include +#include + +using Float = float; +using Vec2 = std::complex; + +const Float eps = 1e-6; + +Float cross(const Vec2& a, const Vec2& b) { + return a.real() * b.imag() - a.imag() * b.real(); +} + +Float dot(const Vec2& a, const Vec2& b) { + return a.real() * b.real() + a.imag() * b.imag(); +} + +struct Circle { + Vec2 o; + Float r; + Circle() {} + Circle(const Vec2& o, Float r): o(o), r(r) {} + bool inside(const Vec2& a) const { + return abs(o - a) <= r; + } +}; + +template +struct Polygon { + std::array vertex; + + Polygon() {} + Polygon(const std::array& v): vertex(v) {} + Vec2& operator[](int i) { + return vertex[i]; + } + + Vec2 operator[](int i) const { + return vertex[i]; + } + + bool inside(const Vec2& a) const { + Float s = 0; + for (int i = 0; i < n; i++) { + Vec2 u = vertex[i] - a, w = vertex[(i + 1) % n] - a; + s += atan2(cross(u, w), dot(u, w)); + } + return abs(s) > eps; + } +}; + +bool intersect(const Circle& a, const Circle& b) { + return abs(a.o - b.o) <= a.r + b.r; +} + +template +bool intersect(const Polygon& a, const Polygon& b) { + for (int i = 0; i < n; i++) { + if (b.inside(a[i])) { + return true; + } + } + + for (int i = 0; i < m; i++) { + if (a.inside(b[i])) { + return true; + } + } + + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + if (cross(b[j] - a[i], a[(i + 1) % n] - a[i]) * cross(b[(j + 1) % m] - a[i], a[(i + 1) % n] - a[i]) <= 0 + && cross(a[i] - b[j], b[(j + 1) % m] - b[j]) * cross(a[(i + 1) % n] - b[j], b[(j + 1) % m] - b[j]) <= 0) { + return true; + } + } + } + return false; +} + +template +bool intersect(const Polygon& a, const Circle& b) { + if (a.inside(b.o)) { + return true; + } + + for (int i = 0; i < n; i++) { + if (b.inside(a[i])) { + return true; + } + } + + for (int i = 0; i < n; i++) { + Vec2 u = b.o - a[i], v = a[(i + 1) % n] - a[i]; + Float c = dot(u, v) / norm(v); + if (0 <= c && c <= 1 && abs(u - c * v) <= b.r) { + return true; + } + + return false; + } +} + +template +bool intersect(const Circle& b, const Polygon& a) { + return intersect(a, b); +} + +#endif