Blame c++/vector/vector.h

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