Blame c++/vector/vector.h

Ivan Mahonin 2fb9fd
#ifndef VECTOR_H
Ivan Mahonin 2fb9fd
#define VECTOR_H
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
#include <cmath>
Ivan Mahonin 145120
Ivan Mahonin 145120
#include <algorithm>
Ivan Mahonin 145120
Ivan Mahonin 2fb9fd
#include "real.h"
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
class Vector {
Ivan Mahonin 2fb9fd
public:
Ivan Mahonin 2fb9fd
	union {
Ivan Mahonin 2fb9fd
		struct { Real x, y; };
Ivan Mahonin 2fb9fd
		struct { Real coords[2]; };
Ivan Mahonin 2fb9fd
	};
Ivan Mahonin 2fb9fd
	
Ivan Mahonin 2fb9fd
	explicit Vector(const Real &x = Real(), const Real &y = Real()): x(x), y(y) { }
Ivan Mahonin 2fb9fd
	
Ivan Mahonin 2fb9fd
	const Real& operator[] (int i) const { return coords[i]; }
Ivan Mahonin 2fb9fd
	Real& operator[] (int i) { return coords[i]; }
Ivan Mahonin 2fb9fd
Ivan Mahonin 145120
	bool operator<(const Vector &a) const { return less(x, a.x) || (!less(a.x, x) && less(y, a.y)); }
Ivan Mahonin 145120
	bool operator==(const Vector &a) const { return equal(x, a.x) && equal(y, a.y); }
Ivan Mahonin 145120
	bool operator!=(const Vector &a) const { return !(*this == a); }
Ivan Mahonin 2fb9fd
Ivan Mahonin 145120
	Vector operator-() const { return Vector(-x, -y); }
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	Vector operator+(const Vector &a) const { return Vector(x + a.x, y + a.y); }
Ivan Mahonin 145120
	Vector operator-(const Vector &a) const { return Vector(x - a.x, y - a.y); }
Ivan Mahonin 145120
	Vector operator*(const Real &a) const { return Vector(x*a, y*a); }
Ivan Mahonin 145120
	Vector operator/(const Real &a) const { return *this * (Real(1)/a); }
Ivan Mahonin 2fb9fd
	
Ivan Mahonin 145120
	Vector& operator+=(const Vector &a) { x += a.x; y += a.y; return *this; }
Ivan Mahonin 145120
	Vector& operator-=(const Vector &a) { x -= a.x; y -= a.y; return *this; }
Ivan Mahonin 145120
	Vector& operator*=(const Real &a) { x *= a; y *= a; return *this; }
Ivan Mahonin 145120
	Vector& operator/=(const Real &a) { return *this *= (Real(1)/a); }
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
	friend inline Vector operator*(const Real &a, const Vector &b) { return b*a; }
Ivan Mahonin 2fb9fd
	friend inline Real dot(const Vector &a, const Vector &b) { return a.x*b.x + a.y*b.y; }
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
	bool iszero() const { return *this == Vector(); }
Ivan Mahonin 2fb9fd
	void reset() { *this = Vector(); }
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
	Real lensqr() const { return dot(*this, *this); }
Ivan Mahonin 2fb9fd
	Real len() const { return sqrt(lensqr()); }
Ivan Mahonin 2fb9fd
Ivan Mahonin a7e4c0
	Vector norm() const { Real l = len(); return equal(l, 0) ? Vector() : *this/l; }
Ivan Mahonin 2fb9fd
	Vector perp() const { return Vector(-y, x); }
Ivan Mahonin 2fb9fd
	Vector scale(const Vector &a) const { return Vector(x*a.x, y*a.y); }
Ivan Mahonin 2fb9fd
	Vector rotate(const Real &angle) const {
Ivan Mahonin 2fb9fd
		Vector a = from_angle(angle);
Ivan Mahonin 2fb9fd
		return Vector(x*a.x - y*a.y, x*a.y + y*a.x);
Ivan Mahonin 2fb9fd
	}
Ivan Mahonin 2fb9fd
	
Ivan Mahonin 2fb9fd
	static Vector from_angle(Real angle)
Ivan Mahonin 2fb9fd
		{ return Vector(cos(angle), sin(angle)); }
Ivan Mahonin 2fb9fd
};
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
Ivan Mahonin 145120
class RealPair {
Ivan Mahonin 2fb9fd
public:
Ivan Mahonin 145120
	Real a0, a1;
Ivan Mahonin 145120
	RealPair(const Real &a0, const Real &a1):
Ivan Mahonin 145120
		a0(a0), a1(a1) { }
Ivan Mahonin 145120
	explicit RealPair(const Real &a = Real()):
Ivan Mahonin 145120
		RealPair(a, a) { }
Ivan Mahonin 145120
	Real dist() const { return a1 - a0; }
Ivan Mahonin 145120
	void reset() { a0 = a1 = Real(); }
Ivan Mahonin 145120
};
Ivan Mahonin 145120
Ivan Mahonin 145120
Ivan Mahonin 145120
class Range: public RealPair {
Ivan Mahonin 145120
public:
Ivan Mahonin 145120
	using RealPair::RealPair;
Ivan Mahonin 145120
	Real size() const { return dist(); }
Ivan Mahonin 145120
	bool isempty() const { return !less(a0, a1); }
Ivan Mahonin 145120
	Range& expand(const Real &a) {
Ivan Mahonin 145120
		if (a < a0) a0 = a;
Ivan Mahonin 145120
		if (a1 < a) a1 = a;
Ivan Mahonin 145120
		return *this;
Ivan Mahonin 2fb9fd
	}
Ivan Mahonin 145120
	Range get_expanded(const Real &a) const
Ivan Mahonin 145120
		{ return Range(std::min(a, a0), std::max(a1, a)); }
Ivan Mahonin 145120
};
Ivan Mahonin 2fb9fd
Ivan Mahonin 145120
Ivan Mahonin 145120
class VectorPair {
Ivan Mahonin 145120
public:
Ivan Mahonin 145120
	Real x0, y0, x1, y1;
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	VectorPair(const Real &x0, const Real &y0, const Real &x1, const Real &y1):
Ivan Mahonin 145120
		x0(x0), y0(y0), x1(x1), y1(y1) { }
Ivan Mahonin 145120
	explicit VectorPair(const Real &x = Real(), const Real &y = Real()):
Ivan Mahonin 145120
		VectorPair(x, y, x, y) { }
Ivan Mahonin 145120
Ivan Mahonin 145120
	VectorPair(const Vector &p0, const Vector &p1):
Ivan Mahonin 145120
		VectorPair(p0.x, p0.y, p1.x, p1.y) { }
Ivan Mahonin 145120
	explicit VectorPair(const Vector &p):
Ivan Mahonin 145120
		VectorPair(p, p) { }
Ivan Mahonin 145120
Ivan Mahonin 145120
	VectorPair(const RealPair &x, const RealPair &y):
Ivan Mahonin 145120
		VectorPair(x.a0, y.a0, x.a1, y.a1) { }
Ivan Mahonin 145120
Ivan Mahonin 145120
	Vector& p0() { return *(Vector*)&x0; };
Ivan Mahonin 145120
	Vector& p1() { return *(Vector*)&x1; };
Ivan Mahonin 145120
	const Vector& p0() const { return *(const Vector*)&x0; };
Ivan Mahonin 145120
	const Vector& p1() const { return *(const Vector*)&x1; };
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	Vector dist() const { return p1() - p0(); }
Ivan Mahonin 145120
	Real dist_x() const { return x1 - x0; }
Ivan Mahonin 145120
	Real dist_y() const { return y1 - y0; }
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	void reset() { p0().reset(); p1().reset(); }
Ivan Mahonin 145120
};
Ivan Mahonin 145120
Ivan Mahonin 145120
Ivan Mahonin 145120
class Rect: public VectorPair {
Ivan Mahonin 145120
public:
Ivan Mahonin 145120
	using VectorPair::VectorPair;
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	Vector size() const { return dist(); }
Ivan Mahonin 145120
	Real width() const { return dist_x(); }
Ivan Mahonin 145120
	Real height() const { return dist_y(); }
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	bool isempty() const { return !less(x0, x1) || !less(y0, y1); }
Ivan Mahonin 145120
	
Ivan Mahonin 145120
	Rect& expand(const Real &x, const Real &y) {
Ivan Mahonin 145120
		if (x0 < x) x0 = x;
Ivan Mahonin 145120
		if (y0 < y) y0 = y;
Ivan Mahonin 145120
		if (x1 < x) x1 = x;
Ivan Mahonin 145120
		if (y1 < y) y1 = y;
Ivan Mahonin 145120
		return *this;
Ivan Mahonin 2fb9fd
	}
Ivan Mahonin 145120
	Rect& expand(const Vector &p)
Ivan Mahonin 145120
		{ return expand(p.x, p.y); }
Ivan Mahonin 2fb9fd
Ivan Mahonin 145120
	Rect get_expanded(const Real &x, const Real &y) const
Ivan Mahonin 145120
		{ return Rect(std::min(x0, x), std::min(y0, y), std::max(x1, x), std::max(y1, y)); }
Ivan Mahonin 145120
	Rect get_expanded(const Vector &p) const
Ivan Mahonin 145120
		{ return get_expanded(p.x, p.y); }
Ivan Mahonin 2fb9fd
};
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
Ivan Mahonin 2fb9fd
#endif