I tried multiplying X rotation and Y rotation. Got the calculations. But if I try Y then X rotation. They both give me the same evalutation.
#ifndef MATRIX3_H_
#define MATRIX3_H_
#include <iostream>
#include <iomanip>
#include <tr1/array>
#include <cassert>
#include <algorithm>
#include "Vector.h"
#include "Math.h"
#define MAT3_INLINE __attribute__((always_inline))
namespace Eckos
{
template<typename Real>
//! Matrix3x3 Math class
class Matrix3
{
public:
//! Anonymous Union
union
{
//! Matrix Array
/*!
Holds the matrix data in this array for easy access. Sharing data with the m11 ... m33 variables
*/
std::tr1::array<Real, 9> mat;
//! Anonymous struct
struct
{
Real m11, m12, m13,
m21, m22, m23,
m31, m32, m33;
};
};
//! Explicit default constructor
explicit Matrix3()
{
// Set to identity
*this = identity();
}
//! Explicit constructor
/*!
Follows the OpenGL matrix style
\param m11 mat[0]
\param m21 mat[3]
\param m31 mat[6]
\param m12 mat[1]
\param m22 mat[4]
\param m32 mat[7]
\param m13 mat[2]
\param m23 mat[5]
\param m33 mat[8]
*/
explicit Matrix3(Real m11, Real m21, Real m31,
Real m12, Real m22, Real m32,
Real m13, Real m23, Real m33)
{
mat[0] = m11; mat[3] = m21; mat[6] = m31;
mat[1] = m12; mat[4] = m22; mat[7] = m32;
mat[2] = m13; mat[5] = m23; mat[8] = m33;
}
//! Copy constructor
/*!
Copies the given Matrix to this Matrix
\param m Given Matrix
*/
Matrix3(const Matrix3& m)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat = m.mat;
}
}
//! Copy constructor
/*!
Copies the given scalar to this Matrix
\param scalar Matrix scalar
*/
Matrix3(const Real scalar)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat = scalar;
}
}
//! Overloaded operator=
/*!
Assigns the given Matrix to this Matrix
\param m Given Matrix
*/
MAT3_INLINE void operator=(const Matrix3& m)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat = m.mat;
}
}
//! Overloaded operator=
/*!
Assigns the given scalar to this Matrix
\param scalar Matrix scalar
*/
MAT3_INLINE void operator=(const Real scalar)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat = scalar;
}
}
//! Overloaded operator+
/*!
Adds the given Matrix to this Matrix
\param m Given Matrix
\return Addition result
*/
MAT3_INLINE Matrix3 operator+(const Matrix3& m)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
tmp.mat = mat + m.mat;
}
return tmp;
}
//! Overloaded operator+=
/*!
Adds the given Matrix with this Matrix
\param m Given Matrix
\return Addition result
*/
MAT3_INLINE Matrix3& operator+=(const Matrix3& m)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat += m.mat;
}
return *this;
}
//! Overloaded operator+
/*!
Adds the given scalar with this Matrix
\param scalar Matrix scalar
\return Addition result
*/
MAT3_INLINE Matrix3 operator+(const Real scalar)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
tmp.mat = mat + scalar;
}
return tmp;
}
//! Overloaded operator+=
/*!
Adds the given scalar to this Matrix
\param scalar Matrix scalar
\return Addition result
*/
MAT3_INLINE Matrix3& operator+=(const Real scalar)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat += scalar;
}
return *this;
}
//! Overloaded operator-
/*!
Subtracts the given Matrix from this Matrix
\param m Given Matrix
\return Subtraction result
*/
MAT3_INLINE Matrix3 operator-(const Matrix3& m)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
tmp,mat = mat - m.mat;
}
return tmp;
}
//! Overloaded operator-=
/*!
Subtracts the given Matrix from this Matrix
\param m Given Matrix
\return Subtraction result
*/
MAT3_INLINE Matrix3& operator-=(const Matrix3& m)
{
for(unsigned i = 0; i < mat.size(); ++i)
{
mat -= m.mat;
}
return *this;
}
//! Overloaded operator-
/*!
Subtracts the given Matrix scalar from this Matrix
\param scalar Matrix scalar
\return Subtraction result
*/
MAT3_INLINE Matrix3 operator-(const Real scalar)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
tmp.mat = mat - scalar;
}
return tmp;
}
//! Overloaded operator-=
/*!
Subtracts the given Matrix scalar from this Matrix
\param scalar Matrix scalar
\return Subtraction result
*/
MAT3_INLINE Matrix3& operator-=(const Real scalar)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
mat -= scalar;
}
return *this;
}
//! Overloaded operator*
/*!
Multiplies the given Matrix with this Matrix
\param m Given Matrix
\return Multiplied result
*/
MAT3_INLINE Matrix3 operator*(const Matrix3& m)
{
return Matrix3(mat[0] * m.mat[0] + mat[3] * m.mat[1] + mat[6] * m.mat[2],
mat[0] * m.mat[3] + mat[3] * m.mat[4] + mat[6] * m.mat[5],
mat[0] * m.mat[6] + mat[3] * m.mat[7] + mat[6] * m.mat[8],
mat[1] * m.mat[0] + mat[4] * m.mat[1] + mat[7] * m.mat[2],
mat[1] * m.mat[3] + mat[4] * m.mat[4] + mat[7] * m.mat[5],
mat[1] * m.mat[6] + mat[4] * m.mat[7] + mat[7] * m.mat[8],
mat[2] * m.mat[0] + mat[5] * m.mat[1] + mat[8] * m.mat[2],
mat[2] * m.mat[3] + mat[5] * m.mat[4] + mat[8] * m.mat[5],
mat[2] * m.mat[6] + mat[5] * m.mat[7] + mat[8] * m.mat[8]);
}
//! Overloaded operator*=
/*!
Multiplies the given Matrix with this Matrix
\param m Given Matrix
\return Multiplied result
*/
MAT3_INLINE Matrix3 operator*=(const Matrix3& m)
{
return Matrix3(mat[0] * m.mat[0] + mat[3] * m.mat[1] + mat[6] * m.mat[2],
mat[0] * m.mat[3] + mat[3] * m.mat[4] + mat[6] * m.mat[5],
mat[0] * m.mat[6] + mat[3] * m.mat[7] + mat[6] * m.mat[8],
mat[1] * m.mat[0] + mat[4] * m.mat[1] + mat[7] * m.mat[2],
mat[1] * m.mat[3] + mat[4] * m.mat[4] + mat[7] * m.mat[5],
mat[1] * m.mat[6] + mat[4] * m.mat[7] + mat[7] * m.mat[8],
mat[2] * m.mat[0] + mat[5] * m.mat[1] + mat[8] * m.mat[2],
mat[2] * m.mat[3] + mat[5] * m.mat[4] + mat[8] * m.mat[5],
mat[2] * m.mat[6] + mat[5] * m.mat[7] + mat[8] * m.mat[8]);
}
//! Overloaded operator*
/*!
Multiplies the given Matrix scalar with this matrix
\param scalar Matrix scalar
\return Multipled result
*/
MAT3_INLINE Matrix3 operator*(const Real scalar)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
tmp.mat = mat * scalar;
}
return tmp;
}
//! Overloaded operator*=
/*!
Multiplies the given Matrix scalar with this matrix
\param scalar Matrix scalar
\return Multipled result
*/
MAT3_INLINE Matrix3& operator*=(const Real scalar)
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
mat *= scalar;
}
return *this;
}
//! Create identity Matrix
/*!
Sets the Matrix to it's identity
\return The Identity Matrix
*/
MAT3_INLINE static Matrix3 identity()
{
return Matrix3(1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0);
}
//! Check for identity Matrix
/*!
Check to see if this Matrix is an identity Matrix or not.
\return true if it's the identity, false otherwise
*/
MAT3_INLINE bool isIdentity()
{
Matrix3 tmp;
for(unsigned i = 0; i < mat.size(); ++i)
{
if(mat != tmp.mat)
{
return false;
}
}
return true;
}
//! Create zero Matrix
/*!
Sets the Matrix to zero
\return Zero Matrix
*/
MAT3_INLINE static Matrix3 zero()
{
return Matrix3(0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 0.0);
}
//! Check for zero Matrix
/*!
Check to see if this Matrix is an identity Matrix or not.
\return true if it's the identity, false otherwise
*/
MAT3_INLINE bool isZero()
{
Matrix3 tmp = zero();
for(unsigned i = 0; i < mat.size(); ++i)
{
if(mat != tmp.mat)
{
return false;
}
}
return true;
}
//! Transpose this Matrix
/*!
Transpose by swaping the columns and rows
\return Tranposed Matrix
*/
MAT3_INLINE void transpose()
{
std::swap(mat[1], mat[3]);
std::swap(mat[2], mat[6]);
std::swap(mat[5], mat[7]);
}
//! Rotate the matrix around the X axis
/*!
\param angle Angle of degrees which to rotate
\return The rotated Matrix
*/
MAT3_INLINE Matrix3& rotateXAxis(Real angle)
{
Real cos = Math<Real>::cosine(angle);
Real sin = Math<Real>::sine(angle);
mat[4] = cos;
mat[5] = -sin;
mat[7] = sin;
mat[8] = cos;
return *this;
}
//! Rotate the Matrix around the Y axis
/*!
\param angle Angle of degrees which to rotate
\return The rotated Matrix
*/
MAT3_INLINE Matrix3& rotateYAxis(Real angle)
{
Real cos = Math<Real>::cosine(angle);
Real sin = Math<Real>::sine(angle);
mat[0] = cos;
mat[2] = sin;
mat[6] = -sin;
mat[8] = cos;
return *this;
}
//! Rotate the Matrix around the Z axis
/*!
\param angle Angle of degrees which to rotate
\return The rotated Matrix
*/
MAT3_INLINE Matrix3& rotateZAxis(Real angle)
{
Real cos = Math<Real>::cosine(angle);
Real sin = Math<Real>::sine(angle);
mat[0] = cos;
mat[1] = -sin;
mat[3] = sin;
mat[4] = cos;
return *this;
}
//! Scale the Matrix
/*!
Scales the current Matrix around X, Y, or Z axis or all.
\param _x X axis
\param _y Y axis
\param _z Z axis
\return The scaled Matrix
*/
MAT3_INLINE Matrix3& scale(const Real _x, const Real _y, const Real _z)
{
*this = identity();
mat[0] = _x;
mat[4] = _y;
mat[8] = _z;
return *this;
}
//! Scale all the axis for this Matrix
/*!
Scales the current Matrix using all the axis with constant value for each
\param v Given vector
\return The scaled Matrix
*/
MAT3_INLINE Matrix3& scale(const Vector3<Real>& v)
{
scale(v.x, v.y, v.z);
return *this;
}
MAT3_INLINE void print()
{
for(unsigned i = 0; i < 3; ++i)
{
std::cout << std::fixed << std::setprecision(5)
<< "[ " << mat << ", " << mat << <span class="cpp-literal">", "</span> << mat << <span class="cpp-literal">" ]"</span>
<< std::endl;
}
std::cout << std::endl;
}
<span class="cpp-comment">//! Pointer to the Matrix array</span>
<span class="cpp-comment">/*!
Returns the array for easy access to the Matrix array.
\return Pointer to the mat Matrix array
*/</span>
MAT3_INLINE <span class="cpp-keyword">const</span> Real* ptr()
{
<span class="cpp-keyword">return</span> mat.data();
}
<span class="cpp-comment">//! Matrix size</span>
<span class="cpp-comment">/*!
Length of the mat Matrix array
\return Length of the Matrix array
*/</span>
MAT3_INLINE size_t size()
{
<span class="cpp-keyword">return</span> mat.size();
}
<span class="cpp-comment">//! Determinant of the current Matrix</span>
<span class="cpp-comment">/*!
Finds the determinant of the Matrix
\return Determinant value
*/</span>
MAT3_INLINE Real determinant()
{
<span class="cpp-keyword">return</span> determinant(mat[<span class="cpp-number">0</span>], mat[<span class="cpp-number">3</span>], mat[<span class="cpp-number">6</span>],
mat[<span class="cpp-number">1</span>], mat[<span class="cpp-number">4</span>], mat[<span class="cpp-number">7</span>],
mat[<span class="cpp-number">2</span>], mat[<span class="cpp-number">5</span>], mat[<span class="cpp-number">8</span>]);
}
<span class="cpp-comment">//! Determinant of the 2x2 Matrix</span>
<span class="cpp-comment">/*!
Finds the determinant of the 2x2 Matrix (minor)
\return Determinant value
*/</span>
MAT3_INLINE Real determinant(Real a, Real b,
Real c, Real d)
{
<span class="cpp-keyword">return</span> a * b - c * d;
}
<span class="cpp-comment">//! Determinant of the 3x3 Matrix</span>
<span class="cpp-comment">/*!
Finds the determinant of the 3x3 Matrix(minor)
*/</span>
MAT3_INLINE Real determinant(Real a, Real b, Real c,
Real d, Real e, Real f,
Real g, Real h, Real i)
{
Real a1 = a * determinant(e, i, f, h);
Real b1 = b * determinant(d, i, f, g);
Real c1 = c * determinant(d, h, e, g);
<span class="cpp-keyword">return</span> +a1 - b1 + c1;
}
<span class="cpp-comment">//! Finds the inverse of this Matrix</span>
<span class="cpp-comment">/*!
Determines the inverse of this Matrix
\param inverse Out parameter that if true it is inversed, false if not.
\return The inverse
*/</span>
MAT3_INLINE Matrix3 inverse(<span class="cpp-keyword">bool</span> *inverse = <span class="cpp-keyword">false</span>)
{
Matrix3 tmpMat = Matrix3();
tmpMat.mat[<span class="cpp-number">0</span>] = determinant(mat[<span class="cpp-number">4</span>], mat[<span class="cpp-number">8</span>], mat[<span class="cpp-number">7</span>], mat[<span class="cpp-number">5</span>]);
tmpMat.mat[<span class="cpp-number">1</span>] = -determinant(mat[<span class="cpp-number">3</span>], mat[<span class="cpp-number">8</span>], mat[<span class="cpp-number">6</span>], mat[<span class="cpp-number">5</span>]);
tmpMat.mat[<span class="cpp-number">2</span>] = determinant(mat[<span class="cpp-number">3</span>], mat[<span class="cpp-number">7</span>], mat[<span class="cpp-number">6</span>], mat[<span class="cpp-number">4</span>]);
tmpMat.mat[<span class="cpp-number">3</span>] = -determinant(mat[<span class="cpp-number">1</span>], mat[<span class="cpp-number">8</span>], mat[<span class="cpp-number">7</span>], mat[<span class="cpp-number">2</span>]);
tmpMat.mat[<span class="cpp-number">4</span>] = determinant(mat[<span class="cpp-number">0</span>], mat[<span class="cpp-number">8</span>], mat[<span class="cpp-number">6</span>], mat[<span class="cpp-number">2</span>]);
tmpMat.mat[<span class="cpp-number">5</span>] = -determinant(mat[<span class="cpp-number">0</span>], mat[<span class="cpp-number">7</span>], mat[<span class="cpp-number">6</span>], mat[<span class="cpp-number">1</span>]);
tmpMat.mat[<span class="cpp-number">6</span>] = determinant(mat[<span class="cpp-number">1</span>], mat[<span class="cpp-number">5</span>], mat[<span class="cpp-number">4</span>], mat[<span class="cpp-number">2</span>]);
tmpMat.mat[<span class="cpp-number">7</span>] = -determinant(mat[<span class="cpp-number">0</span>], mat[<span class="cpp-number">5</span>], mat[<span class="cpp-number">3</span>], mat[<span class="cpp-number">2</span>]);
tmpMat.mat[<span class="cpp-number">8</span>] = determinant(mat[<span class="cpp-number">0</span>], mat[<span class="cpp-number">4</span>], mat[<span class="cpp-number">3</span>], mat[<span class="cpp-number">1</span>]);
tmpMat.transpose();
Real det = determinant();
<span class="cpp-keyword">if</span>(det == <span class="cpp-number">0</span>)
{
*inverse = <span class="cpp-keyword">false</span>;
<span class="cpp-keyword">return</span> Matrix3::identity();
}
<span class="cpp-keyword">for</span>(<span class="cpp-keyword">unsigned</span> i = <span class="cpp-number">0</span>; i < mat.size(); ++i)
{
tmpMat.mat<span style="font-weight:bold;"> /= det;
}
*inverse = <span class="cpp-keyword">true</span>;
<span class="cpp-keyword">return</span> tmpMat;
}
}; <span class="cpp-comment">/*class Matrix3*/</span>
<span class="cpp-keyword">typedef</span> Matrix3<<span class="cpp-keyword">double</span>> Matrix3d;
<span class="cpp-keyword">typedef</span> Matrix3<<span class="cpp-keyword">float</span>> Matrix3f;
};<span class="cpp-comment">/* namespace Eckos*/</span>
<span class="cpp-directive">#endif</span> <span class="cpp-comment">/*MATRIX3_H_*/</span>
</pre></div><!–ENDSCRIPT–>