|
|
14f971 |
#ifndef MATRIX_H
|
|
|
14f971 |
#define MATRIX_H
|
|
|
14f971 |
|
|
|
14f971 |
|
|
|
0662a2 |
#include <cairomm matrix.h=""></cairomm>
|
|
|
0662a2 |
|
|
|
14f971 |
#include "vector.h"
|
|
|
14f971 |
|
|
|
14f971 |
|
|
|
4dc49c |
|
|
|
4dc49c |
class Matrix3 {
|
|
|
4dc49c |
public:
|
|
|
4dc49c |
union {
|
|
|
4dc49c |
struct {
|
|
|
4dc49c |
Real m00, m01, m02,
|
|
|
4dc49c |
m10, m11, m12,
|
|
|
4dc49c |
m20, m21, m22;
|
|
|
4dc49c |
};
|
|
|
4dc49c |
struct { Real m[3][3]; };
|
|
|
4dc49c |
struct { Real a[9]; };
|
|
|
4dc49c |
};
|
|
|
4dc49c |
|
|
|
4dc49c |
inline explicit Matrix3(
|
|
|
4dc49c |
const Vector3 &x = Vector3(1, 0, 0),
|
|
|
4dc49c |
const Vector3 &y = Vector3(0, 1, 0),
|
|
|
4dc49c |
const Vector3 &z = Vector3(0, 0, 1)
|
|
|
4dc49c |
):
|
|
|
4dc49c |
m00(x.x), m01(x.y), m02(x.z),
|
|
|
4dc49c |
m10(y.x), m11(y.y), m12(y.z),
|
|
|
4dc49c |
m20(z.x), m21(z.y), m22(z.z) { }
|
|
|
4dc49c |
|
|
|
4dc49c |
inline Vector3& operator[] (int index) { return Vector3::cast(m[index]); }
|
|
|
4dc49c |
inline const Vector3& operator[] (int index) const { return Vector3::cast(m[index]); }
|
|
|
4dc49c |
|
|
|
4dc49c |
inline Vector3& row_x() { return (*this)[0]; }
|
|
|
4dc49c |
inline Vector3& row_y() { return (*this)[1]; }
|
|
|
4dc49c |
inline Vector3& row_z() { return (*this)[2]; }
|
|
|
4dc49c |
|
|
|
4dc49c |
inline const Vector3& row_x() const { return (*this)[0]; }
|
|
|
4dc49c |
inline const Vector3& row_y() const { return (*this)[1]; }
|
|
|
4dc49c |
inline const Vector3& row_z() const { return (*this)[2]; }
|
|
|
4dc49c |
|
|
|
4dc49c |
inline const Vector3 get_col(int index) const
|
|
|
4dc49c |
{ return Vector3( m[0][index], m[1][index], m[2][index] ); }
|
|
|
4dc49c |
|
|
|
4dc49c |
inline Vector3 operator* (const Vector3 &v) const
|
|
|
4dc49c |
{ return row_x()*v.x + row_y()*v.y + row_z()*v.z; }
|
|
|
4dc49c |
inline Matrix3 operator* (const Matrix3 &other) const {
|
|
|
4dc49c |
return Matrix3( *this * other.row_x(),
|
|
|
4dc49c |
*this * other.row_y(),
|
|
|
4dc49c |
*this * other.row_z() );
|
|
|
4dc49c |
}
|
|
|
4dc49c |
|
|
|
4dc49c |
inline Matrix3& operator*= (const Matrix3 &other)
|
|
|
4dc49c |
{ return *this = *this * other; }
|
|
|
4dc49c |
|
|
|
4dc49c |
Real det() const;
|
|
|
4dc49c |
Matrix3 inverted(bool *success = NULL) const;
|
|
|
4dc49c |
inline Matrix3& invert(bool *success = NULL)
|
|
|
4dc49c |
{ return *this = inverted(); }
|
|
|
4dc49c |
|
|
|
4dc49c |
static Real det(const Matrix3 matrix, const Matrix3 preinverted_matrix);
|
|
|
4dc49c |
static inline Matrix3 zero() { return Matrix3(Vector3(), Vector3(), Vector3()); }
|
|
|
4dc49c |
|
|
|
4dc49c |
static inline Matrix3 identity() { return Matrix3(); }
|
|
|
4dc49c |
static inline Matrix3 translation(const Vector2 &v) {
|
|
|
4dc49c |
return Matrix3(
|
|
|
4dc49c |
Vector3(1, 0, 0),
|
|
|
4dc49c |
Vector3(0, 1, 0),
|
|
|
4dc49c |
Vector3(v , 1) );
|
|
|
4dc49c |
}
|
|
|
4dc49c |
static inline Matrix3 scaling(const Vector2 &v) {
|
|
|
4dc49c |
return Matrix3(
|
|
|
4dc49c |
Vector3(v.x, 0, 0),
|
|
|
4dc49c |
Vector3( 0, v.y, 0),
|
|
|
4dc49c |
Vector3( 0, 0, 1) );
|
|
|
4dc49c |
}
|
|
|
4dc49c |
|
|
|
4dc49c |
std::string to_string() const {
|
|
|
4dc49c |
return "(" + row_x().to_string() + ", "
|
|
|
4dc49c |
+ row_y().to_string() + ", "
|
|
|
4dc49c |
+ row_z().to_string() + ")";
|
|
|
4dc49c |
}
|
|
|
4dc49c |
|
|
|
4dc49c |
Cairo::Matrix to_cairo() const {
|
|
|
4dc49c |
return Cairo::Matrix(
|
|
|
4dc49c |
m00, m10, m01,
|
|
|
4dc49c |
m11, m20, m21 );
|
|
|
4dc49c |
}
|
|
|
4dc49c |
};
|
|
|
4dc49c |
|
|
|
4dc49c |
|
|
|
14f971 |
class Matrix4 {
|
|
|
14f971 |
public:
|
|
|
14f971 |
union {
|
|
|
14f971 |
struct {
|
|
|
14f971 |
Real m00, m01, m02, m03,
|
|
|
14f971 |
m10, m11, m12, m13,
|
|
|
14f971 |
m20, m21, m22, m23,
|
|
|
14f971 |
m30, m31, m32, m33;
|
|
|
14f971 |
};
|
|
|
14f971 |
struct { Real m[4][4]; };
|
|
|
14f971 |
struct { Real a[16]; };
|
|
|
14f971 |
};
|
|
|
14f971 |
|
|
|
14f971 |
inline explicit Matrix4(
|
|
|
14f971 |
const Vector4 &x = Vector4(1, 0, 0, 0),
|
|
|
14f971 |
const Vector4 &y = Vector4(0, 1, 0, 0),
|
|
|
14f971 |
const Vector4 &z = Vector4(0, 0, 1, 0),
|
|
|
14f971 |
const Vector4 &w = Vector4(0, 0, 0, 1)
|
|
|
14f971 |
):
|
|
|
14f971 |
m00(x.x), m01(x.y), m02(x.z), m03(x.w),
|
|
|
14f971 |
m10(y.x), m11(y.y), m12(y.z), m13(y.w),
|
|
|
14f971 |
m20(z.x), m21(z.y), m22(z.z), m23(z.w),
|
|
|
14f971 |
m30(w.x), m31(w.y), m32(w.z), m33(w.w) { }
|
|
|
14f971 |
|
|
|
14f971 |
inline Vector4& operator[] (int index) { return Vector4::cast(m[index]); }
|
|
|
14f971 |
inline const Vector4& operator[] (int index) const { return Vector4::cast(m[index]); }
|
|
|
14f971 |
|
|
|
14f971 |
inline Vector4& row_x() { return (*this)[0]; }
|
|
|
14f971 |
inline Vector4& row_y() { return (*this)[1]; }
|
|
|
14f971 |
inline Vector4& row_z() { return (*this)[2]; }
|
|
|
14f971 |
inline Vector4& row_w() { return (*this)[3]; }
|
|
|
14f971 |
|
|
|
14f971 |
inline const Vector4& row_x() const { return (*this)[0]; }
|
|
|
14f971 |
inline const Vector4& row_y() const { return (*this)[1]; }
|
|
|
14f971 |
inline const Vector4& row_z() const { return (*this)[2]; }
|
|
|
14f971 |
inline const Vector4& row_w() const { return (*this)[3]; }
|
|
|
14f971 |
|
|
|
14f971 |
inline Vector4 operator* (const Vector4 &v) const
|
|
|
14f971 |
{ return row_x()*v.x + row_y()*v.y + row_z()*v.z + row_w()*v.w; }
|
|
|
14f971 |
inline Matrix4 operator* (const Matrix4 &other) const {
|
|
|
14f971 |
return Matrix4( *this * other.row_x(),
|
|
|
14f971 |
*this * other.row_y(),
|
|
|
14f971 |
*this * other.row_z(),
|
|
|
14f971 |
*this * other.row_w() );
|
|
|
14f971 |
}
|
|
|
14f971 |
|
|
|
14f971 |
inline Matrix4& operator*= (const Matrix4 &other)
|
|
|
14f971 |
{ return *this = *this * other; }
|
|
|
14f971 |
|
|
|
a1942e |
Real det() const;
|
|
|
a1942e |
Matrix4 inverted() const;
|
|
|
a1942e |
Matrix4& invert()
|
|
|
a1942e |
{ return *this = inverted(); }
|
|
|
a1942e |
|
|
|
a1942e |
Matrix4& scale(Real x, Real y, Real z = 1.0) {
|
|
|
a1942e |
row_x().vec3() *= x;
|
|
|
a1942e |
row_y().vec3() *= y;
|
|
|
a1942e |
row_z().vec3() *= z;
|
|
|
a1942e |
return *this;
|
|
|
a1942e |
}
|
|
|
a1942e |
Matrix4 scaled(Real x, Real y, Real z = 1.0)
|
|
|
a1942e |
{ return Matrix4(*this).scale(x, y, z); }
|
|
|
a1942e |
|
|
|
14f971 |
static inline Matrix4 zero() { return Matrix4(Vector4(), Vector4(), Vector4(), Vector4()); }
|
|
|
14f971 |
static inline Matrix4 identity() { return Matrix4(); }
|
|
|
a1942e |
|
|
|
a1942e |
std::string to_string() const {
|
|
|
a1942e |
return "(" + row_x().to_string() + ", "
|
|
|
a1942e |
+ row_y().to_string() + ", "
|
|
|
a1942e |
+ row_z().to_string() + ", "
|
|
|
a1942e |
+ row_w().to_string() + ")";
|
|
|
a1942e |
}
|
|
|
0662a2 |
|
|
|
0662a2 |
Cairo::Matrix to_cairo() const {
|
|
|
0662a2 |
return Cairo::Matrix(
|
|
|
0662a2 |
m00, m10, m01,
|
|
|
0662a2 |
m11, m30, m31 );
|
|
|
0662a2 |
}
|
|
|
14f971 |
};
|
|
|
14f971 |
|
|
|
14f971 |
|
|
|
14f971 |
typedef Matrix4 Matrix;
|
|
|
14f971 |
|
|
|
14f971 |
|
|
|
14f971 |
#endif
|