CP Notebook

← all snippets

Point3D

Class to handle points in 3D space. T can be e.g. double or long long.

31 lines tested, except for phi and theta

content/geometry/Point3D.h — Ulf Lundstrom with inspiration from tinyKACTL

template<class T> struct Point3D {
	typedef Point3D P;
	T x, y, z;
	explicit Point3D(T x=0, T y=0, T z=0) : x(x), y(y), z(z) {}
	bool operator<(P p) const {
		return tie(x, y, z) < tie(p.x, p.y, p.z); }
	bool operator==(P p) const {
		return tie(x, y, z) == tie(p.x, p.y, p.z); }
	P operator+(P p) const { return P(x+p.x, y+p.y, z+p.z); }
	P operator-(P p) const { return P(x-p.x, y-p.y, z-p.z); }
	P operator*(T d) const { return P(x*d, y*d, z*d); }
	P operator/(T d) const { return P(x/d, y/d, z/d); }
	T dot(P p) const { return x*p.x + y*p.y + z*p.z; }
	P cross(P p) const {
		return P(y*p.z - z*p.y, z*p.x - x*p.z, x*p.y - y*p.x);
	}
	T dist2() const { return x*x + y*y + z*z; }
	double dist() const { return sqrt((double)dist2()); }
	//Azimuthal angle (longitude) to x-axis in interval [-pi, pi]
	double phi() const { return atan2(y, x); }
	//Zenith angle (latitude) to the z-axis in interval [0, pi]
	double theta() const { return atan2(sqrt(x*x+y*y),z); }
	P unit() const { return *this/(T)dist(); } //makes dist()=1
	//returns unit vector normal to *this and p
	P normal(P p) const { return cross(p).unit(); }
	//returns point rotated 'angle' radians ccw around axis
	P rotate(double angle, P axis) const {
		double s = sin(angle), c = cos(angle); P u = axis.unit();
		return u*dot(u)*(1-c) + (*this)*c - cross(u)*s;
	}
};