geometry/point3d.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include<bits/stdc++.h> | ||
| 4 | |||
| 5 | const double PI = acos(-1.); | ||
| 6 | const double TAU = 2 * PI; | ||
| 7 | |||
| 8 | template <typename T, typename AreaT=T, typename VolT=T> struct Point3D { | ||
| 9 | using P = Point3D; | ||
| 10 | |||
| 11 | T x, y, z; | ||
| 12 | ✗ | Point3D() : x(0), y(0), z(0) {} | |
| 13 | ✗ | Point3D(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {} | |
| 14 | |||
| 15 | ✗ | template <typename U, typename V, typename W> explicit Point3D(const Point3D<U, V, W>& p) : x(T(p.x)), y(T(p.y)), z(T(p.z)) {} | |
| 16 | |||
| 17 | ✗ | friend std::istream& operator >> (std::istream& i, P& p) { return i >> p.x >> p.y >> p.z; } | |
| 18 | ✗ | friend std::ostream& operator << (std::ostream& o, const P& p) { return o << "(" << p.x << "," << p.y << "," << p.z << ")"; } | |
| 19 | |||
| 20 | ✗ | friend bool operator == (const P& a, const P& b) { return a.x == b.x && a.y == b.y && a.z == b.z; } | |
| 21 | ✗ | friend bool operator != (const P& a, const P& b) { return a.x != b.x || a.y != b.y || a.z != b.z; } | |
| 22 | |||
| 23 | ✗ | P& operator += (const P& o) { x += o.x, y += o.y, z += o.z; return *this; } | |
| 24 | ✗ | P& operator -= (const P& o) { x -= o.x, y -= o.y, z -= o.z; return *this; } | |
| 25 | ✗ | friend P operator + (const P& a, const P& b) { return P(a) += b; } | |
| 26 | ✗ | friend P operator - (const P& a, const P& b) { return P(a) -= b; } | |
| 27 | |||
| 28 | ✗ | P& operator *= (const T& t) { x *= t, y *= t, z *= t; return *this; } | |
| 29 | ✗ | P& operator /= (const T& t) { x /= t, y /= t, z /= t; return *this; } | |
| 30 | ✗ | friend P operator * (const P& p, const T& t) { return P(p) *= t; } | |
| 31 | ✗ | friend P operator * (const T& t, const P& p) { return P(p) *= t; } | |
| 32 | ✗ | friend P operator / (const P& a, const T& t) { return P(a) /= t; } | |
| 33 | |||
| 34 | ✗ | friend P operator + (const P& a) { return P(+a.x, +a.y, +a.z); } | |
| 35 | ✗ | friend P operator - (const P& a) { return P(-a.x, -a.y, -a.z); } | |
| 36 | |||
| 37 | ✗ | friend AreaT dot(const P& a, const P& b) { return AreaT(a.x) * AreaT(b.x) + AreaT(a.y) * AreaT(b.y) + AreaT(a.z) * AreaT(b.z); } | |
| 38 | ✗ | friend AreaT norm(const P& a) { return dot(a,a); } | |
| 39 | // We're playing a little loose with this type, expliitly cast it if you need | ||
| 40 | ✗ | friend Point3D<AreaT, VolT> cross(const P& a, const P& b) { return Point3D<AreaT, VolT>(AreaT(a.y) * AreaT(b.z) - AreaT(a.z) * AreaT(b.y), AreaT(a.z) * AreaT(b.x) - AreaT(a.x) * AreaT(b.z), AreaT(a.x) * AreaT(b.y) - AreaT(a.y) * AreaT(b.x)); } | |
| 41 | |||
| 42 | ✗ | friend T int_norm(const P& p) { | |
| 43 | ✗ | return std::gcd(std::gcd(abs(p.x), abs(p.y)), abs(p.z)); | |
| 44 | } | ||
| 45 | ✗ | friend P int_unit(const P& p) { | |
| 46 | ✗ | T g = int_norm(p); | |
| 47 | ✗ | return g ? p / g : p; | |
| 48 | } | ||
| 49 | |||
| 50 | ✗ | friend T abs(const P& a) { return std::sqrt(std::max(T(0), norm(a))); } | |
| 51 | ✗ | friend P unit(const P& a) { return a / abs(a); } | |
| 52 | |||
| 53 | ✗ | friend VolT vol(const P& a, const P& b, const P& c, const P& d) { return dot(cross(b-a, c-a), Point3D<AreaT, VolT>(d-a)); } | |
| 54 | |||
| 55 | ✗ | friend bool lexLess(const P& a, const P& b) { return std::tie(a.x, a.y, a.z) < std::tie(b.x, b.y, b.z); } | |
| 56 | |||
| 57 | ✗ | friend bool parallelSame(const P& a, const P& b) { | |
| 58 | ✗ | assert(a != P()); | |
| 59 | ✗ | assert(b != P()); | |
| 60 | ✗ | return lexLess(a, P()) == lexLess(b, P()); | |
| 61 | } | ||
| 62 | }; | ||
| 63 |