110 lines
2.6 KiB
C++
110 lines
2.6 KiB
C++
/**
|
|
* Defines a few widely used, widely spread structures. Imported pervasively.
|
|
**/
|
|
|
|
#pragma once
|
|
|
|
#include <functional> // Hash
|
|
#include <vector>
|
|
#include <cassert>
|
|
|
|
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<Point>& 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<Face>
|
|
{
|
|
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<int>{}(s[0]) );
|
|
result_type const h2 ( std::hash<int>{}(s[1]) );
|
|
result_type const h3 ( std::hash<int>{}(s[2]) );
|
|
return h1 ^ h2 ^ h3;
|
|
}
|
|
};
|
|
}
|