|
|
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
|