/** * Defines a few widely used, widely spread structures. Imported pervasively. **/ #pragma once #include // Hash #include #include struct Point { Point(double x, double y, double z) : x(x), y(y), z(z) {} double x, y, z; double operator[](unsigned i) const { assert(i < 3); switch(i) { case 0: return x; case 1: return y; case 2: return z; default: return 0; } } Point operator+(const Point& pt) const { return Point( x + pt.x, y + pt.y, z + pt.z); } Point& operator+=(const Point& pt) { x += pt.x; y += pt.y; z += pt.z; return *this; } Point& operator-=(const Point& pt) { return (*this += Point(-pt.x, -pt.y, -pt.z)); } friend Point operator*(double scalar, const Point& pt) { return Point( scalar * pt.x, scalar * pt.y, scalar * pt.z); } bool operator<(const Point& pt) const { /// Lexicographic order on (x, y, z) if(x == pt.x) { if(y == pt.y) return z < pt.z; return y < pt.y; } return x < pt.x; } }; struct Face { Face(int v0, int v1, int v2) { vert[0] = v0; vert[1] = v1; vert[2] = v2; } int vert[3]; int operator[](unsigned i) const { return vert[i % 3]; // dodge errors } const Point& pt(int id, const std::vector& pts) const { assert(0 <= id && id < 3); return pts[vert[id]]; } }; class Cuboid { /// A 3D box public: static Cuboid empty() { return Cuboid(Point(0, 0, 0), Point(0, 0, 0)); } Cuboid(Point bd1, Point bd2); Cuboid(const Cuboid& oth) : lowBound(oth.lowBound), highBound(oth.highBound) {} double low(unsigned dim) const; ///< Lower bound for a dimension double high(unsigned dim) const; ///< Higher bound for a dimension double volume() const; bool is_empty() const; private: Point lowBound, highBound; }; namespace std { template<> struct hash { typedef Face argument_type; typedef std::size_t result_type; result_type operator()(argument_type const& s) const noexcept { result_type const h1 ( std::hash{}(s[0]) ); result_type const h2 ( std::hash{}(s[1]) ); result_type const h3 ( std::hash{}(s[2]) ); return h1 ^ h2 ^ h3; } }; }