[feat] 2d lib
This commit is contained in:
parent
88a40a11e6
commit
f8902de5e6
112
2d.hpp
Normal file
112
2d.hpp
Normal file
@ -0,0 +1,112 @@
|
||||
#ifndef header_2d
|
||||
#define header_2d
|
||||
|
||||
#include <array>
|
||||
#include <complex>
|
||||
#include <initializer_list>
|
||||
|
||||
using Float = float;
|
||||
using Vec2 = std::complex<Float>;
|
||||
|
||||
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<int n>
|
||||
struct Polygon {
|
||||
std::array<Vec2, n> vertex;
|
||||
|
||||
Polygon() {}
|
||||
Polygon(const std::array<Vec2, n>& 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<int n, int m>
|
||||
bool intersect(const Polygon<n>& a, const Polygon<m>& 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<int n>
|
||||
bool intersect(const Polygon<n>& 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<int n>
|
||||
bool intersect(const Circle& b, const Polygon<n>& a) {
|
||||
return intersect(a, b);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user