#ifndef MATRIX_H
#define MATRIX_H
#include <cairomm/matrix.h>
#include "vector.h"
class Matrix3 {
public:
union {
struct {
Real m00, m01, m02,
m10, m11, m12,
m20, m21, m22;
};
struct { Real m[3][3]; };
struct { Real a[9]; };
};
inline explicit Matrix3(
const Vector3 &x = Vector3(1, 0, 0),
const Vector3 &y = Vector3(0, 1, 0),
const Vector3 &z = Vector3(0, 0, 1)
):
m00(x.x), m01(x.y), m02(x.z),
m10(y.x), m11(y.y), m12(y.z),
m20(z.x), m21(z.y), m22(z.z) { }
inline Vector3& operator[] (int index) { return Vector3::cast(m[index]); }
inline const Vector3& operator[] (int index) const { return Vector3::cast(m[index]); }
inline Vector3& row_x() { return (*this)[0]; }
inline Vector3& row_y() { return (*this)[1]; }
inline Vector3& row_z() { return (*this)[2]; }
inline const Vector3& row_x() const { return (*this)[0]; }
inline const Vector3& row_y() const { return (*this)[1]; }
inline const Vector3& row_z() const { return (*this)[2]; }
inline const Vector3 get_col(int index) const
{ return Vector3( m[0][index], m[1][index], m[2][index] ); }
inline Vector3 operator* (const Vector3 &v) const
{ return row_x()*v.x + row_y()*v.y + row_z()*v.z; }
inline Matrix3 operator* (const Matrix3 &other) const {
return Matrix3( *this * other.row_x(),
*this * other.row_y(),
*this * other.row_z() );
}
inline Matrix3& operator*= (const Matrix3 &other)
{ return *this = *this * other; }
Real det() const;
Matrix3 inverted(bool *success = NULL) const;
inline Matrix3& invert(bool *success = NULL)
{ return *this = inverted(); }
static Real det(const Matrix3 matrix, const Matrix3 preinverted_matrix);
static inline Matrix3 zero() { return Matrix3(Vector3(), Vector3(), Vector3()); }
static inline Matrix3 identity() { return Matrix3(); }
static inline Matrix3 translation(const Vector2 &v) {
return Matrix3(
Vector3(1, 0, 0),
Vector3(0, 1, 0),
Vector3(v , 1) );
}
static inline Matrix3 scaling(const Vector2 &v) {
return Matrix3(
Vector3(v.x, 0, 0),
Vector3( 0, v.y, 0),
Vector3( 0, 0, 1) );
}
std::string to_string() const {
return "(" + row_x().to_string() + ", "
+ row_y().to_string() + ", "
+ row_z().to_string() + ")";
}
Cairo::Matrix to_cairo() const {
return Cairo::Matrix(
m00, m10, m01,
m11, m20, m21 );
}
};
typedef Matrix3 Matrix;
#endif