Blame c++/vector/matrix.h

145120
#ifndef MATRIX_H
145120
#define MATRIX_H
145120
145120
145120
#include <cmath></cmath>
145120
145120
#include "vector.h"
145120
145120
145120
class Matrix {
145120
public:
145120
	union {
145120
		Real m[3][3];
145120
		struct {
145120
			Real m00, m01, m02;
145120
			Real m10, m11, m12;
145120
			Real m20, m21, m22;
145120
		};
145120
	};
145120
145120
	Matrix(
145120
		Real m00, Real m01, Real m02,
145120
		Real m10, Real m11, Real m12,
145120
		Real m20, Real m21, Real m22
145120
	):
145120
		m00(m00), m01(m01), m02(m02),
145120
		m10(m10), m11(m11), m12(m12),
145120
		m20(m20), m21(m21), m22(m22)
145120
	{ }
145120
145120
	Matrix(): Matrix(
145120
		1, 0, 0,
145120
		0, 1, 0,
145120
		0, 0, 1 ) { }
145120
145120
	Matrix(
145120
		const Vector &axis_x,
145120
		const Vector &axis_y,
145120
		const Vector &offset = Vector()
145120
	): Matrix(
145120
		axis_x.x, axis_x.y, 0,
145120
		axis_y.x, axis_y.y, 0,
145120
		offset.x, offset.y, 1 ) { }
145120
145120
	const Vector& axis(int index) const { return *(const Vector*)(m[index]); }
145120
	const Vector& axis_x() const { return axis(0); }
145120
	const Vector& axis_y() const { return axis(1); }
145120
	const Vector& offset() const { return axis(2); }
145120
145120
	Vector& axis(int index) { return *(Vector*)(m[index]); }
145120
	Vector& axis_x() { return axis(0); }
145120
	Vector& axis_y() { return axis(1); }
145120
	Vector& offset() { return axis(2); }
145120
145120
	Matrix& set_identity()
145120
		{ return *this = Matrix(); }
145120
	bool is_identity() const
145120
		{ return *this == Matrix(); }
145120
145120
	Matrix& set_scale(const Real &x, const Real &y) {
145120
		return *this = Matrix( x, 0, 0,
145120
							   0, y, 0,
145120
							   0, 0, 1 );
145120
	}
145120
	Matrix& set_scale(const Real &s)
145120
		{ return set_scale(s, s); }
145120
	Matrix& set_scale(const Vector &s)
145120
		{ return set_scale(s.x, s.y); }
145120
145120
	Matrix& set_rotate(const Real &angle) {
145120
		Real s = sin(angle), c = cos(angle);
145120
		return *this = Matrix( c, s, 0,
145120
							  -s, c, 0,
145120
							   0, 0, 1 );
145120
	}
145120
145120
	Matrix& set_translate(const Real &x, const Real &y) {
145120
		return *this = Matrix( 1, 0, 0,
145120
							   0, 1, 0,
145120
							   x, y, 1 );
145120
	}
145120
	Matrix& set_translate(const Vector &t)
145120
		{ return set_translate(t.x, t.y); }
145120
145120
	void transform(
145120
		Real &out_x, Real &out_y, Real &out_z,
145120
		const Real &x, const Real &y, const Real &z ) const
145120
	{
145120
		out_x = x*m00 + y*m10 + z*m20;
145120
		out_y = x*m01 + y*m11 + z*m21;
145120
		out_z = x*m02 + y*m12 + z*m22;
145120
	}
145120
	void transform(Real &out_x, Real &out_y, const Real &x, const Real &y, bool translate = true) const
145120
		{ Real z; transform(out_x, out_y, z, x, y, translate ? 1.0 : 0.0); }
145120
	Vector transform(const Vector &v, bool translate = true)const
145120
		{ Vector vv; transform(vv.x, vv.y, v.x, v.y, translate); return vv; }
145120
145120
	bool operator==(const Matrix &other) const {
145120
		return equal(m00, other.m00) && equal(m01, other.m01) && equal(m02, other.m02)
145120
			&& equal(m10, other.m10) && equal(m11, other.m11) && equal(m12, other.m12)
145120
			&& equal(m20, other.m20) && equal(m21, other.m21) && equal(m22, other.m22);
145120
	}
145120
	bool operator!=(const Matrix &other) const
145120
		{ return !(*this == other); }
145120
145120
	Matrix& operator*=(const Matrix &other)
145120
		{ return *this = *this * other; }
145120
145120
	Matrix operator*(const Matrix &other) const {
145120
		Matrix m;
145120
		transform(m.m00, m.m01, m.m02, other.m00, other.m01, other.m02);
145120
		transform(m.m10, m.m11, m.m12, other.m10, other.m11, other.m12);
145120
		transform(m.m20, m.m21, m.m22, other.m20, other.m21, other.m22);
145120
		return m;
145120
	}
145120
145120
	Real det() const {
145120
		return m00*(m11*m22 - m12*m21)
145120
			 - m01*(m10*m22 - m12*m20)
145120
			 + m02*(m10*m21 - m11*m20);
145120
	}
145120
	
145120
	bool is_invertible() const
145120
		{ return !equal(det(), 0); }
145120
	
145120
	Matrix get_inverted() const;
145120
145120
	Matrix& invert()
145120
		{ return *this = get_inverted(); }
145120
};
145120
145120
#endif