Blame c++/vector/vector.h

2fb9fd
#ifndef VECTOR_H
2fb9fd
#define VECTOR_H
2fb9fd
2fb9fd
2fb9fd
#include <cmath></cmath>
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
2fb9fd
	bool operator< (const Vector &a) const { return less(x, a.x) || (!less(a.x, x) && less(y, a.y)); }
2fb9fd
	bool operator== (const Vector &a) const { return equal(x, a.x) && equal(y, a.y); }
2fb9fd
	bool operator!= (const Vector &a) const { return !(*this == a); }
2fb9fd
2fb9fd
	Vector operator+ (const Vector &a) const { return Vector(x + a.x, y + a.y); }
2fb9fd
	Vector operator- (const Vector &a) const { return Vector(x - a.x, y - a.y); }
2fb9fd
	Vector operator* (const Real &a) const { return Vector(x*a, y*a); }
2fb9fd
	Vector operator/ (const Real &a) const { return *this * (Real(1)/a); }
2fb9fd
	
2fb9fd
	Vector& operator+= (const Vector &a) { x += a.x; y += a.y; return *this; }
2fb9fd
	Vector& operator-= (const Vector &a) { x -= a.x; y -= a.y; return *this; }
2fb9fd
	Vector& operator*= (const Real &a) { x *= a; y *= a; return *this; }
2fb9fd
	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
2fb9fd
	Vector norm() const { return iszero() ? Vector() : *this/len(); }
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
2fb9fd
class Segment {
2fb9fd
public:
2fb9fd
	Vector p0, p1, t0, t1;
2fb9fd
2fb9fd
	explicit Segment(
2fb9fd
		const Vector &p0 = Vector(),
2fb9fd
		const Vector &p1 = Vector(),
2fb9fd
		const Vector &t0 = Vector(),
2fb9fd
		const Vector &t1 = Vector()
2fb9fd
	):
2fb9fd
		p0(p0), p1(p1), t0(t0), t1(t1) { }
2fb9fd
2fb9fd
	bool operator< (const Segment &a) const {
2fb9fd
		return p0 < a.p0 ? true : a.p0 < p0 ? false
2fb9fd
			 : p1 < a.p1 ? true : a.p1 < p1 ? false
2fb9fd
			 : t0 < a.t0 ? true : a.t0 < t0 ? false
2fb9fd
			 : t1 < a.t1;
2fb9fd
	}
2fb9fd
	bool operator> (const Segment &a) const { return a < *this; }
2fb9fd
	bool operator== (const Segment &a) const { return p0 == a.p0 && p1 == a.p1 && t0 == a.t0 && t1 == a.t1; }
2fb9fd
	bool operator!= (const Segment &a) const { return !(*this == a); }
2fb9fd
2fb9fd
	Vector p(const Real &l) const {
2fb9fd
		return p0*((( 2.0*l - 3.0)*l      )*l + 1.0)
2fb9fd
			 + p1*(((-2.0*l + 3.0)*l      )*l      )
2fb9fd
			 + t0*(((     l - 2.0)*l + 1.0)*l      )
2fb9fd
			 + t1*(((     l - 1.0)*l      )*l      );
2fb9fd
	}
2fb9fd
2fb9fd
	Vector t(const Real &l) const {
2fb9fd
		return p0*(( 6.0*l - 6.0)*l      )
2fb9fd
			 + p1*((-6.0*l + 6.0)*l      )
2fb9fd
			 + t0*(( 3.0*l - 4.0)*l + 1.0)
2fb9fd
			 + t1*(( 3.0*l - 2.0)*l      );
2fb9fd
	}
2fb9fd
2fb9fd
	Vector operator() (const Real &l) const  { return p(l); }
2fb9fd
	Segment sub(const Real &a, const Real &b) const { return Segment(p(a), p(b), t(a), t(b)); }
2fb9fd
};
2fb9fd
2fb9fd
2fb9fd
#endif