Rotation problem

Started by
1 comment, last by Sbronz 15 years, 10 months ago
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.

int main()
{
	Matrix3d d, d1, d2;
	d = d.rotateXAxis(90.0) * d.rotateYAxis(90.0);
	d.print();

	d1 = d1.rotateYAxis(90.0) * d1.rotateXAxis(90.0);
	d1.print();
	return 0;
}



#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 &lt;&lt; <span class="cpp-literal">", "</span> &lt;&lt; mat &lt;&lt; <span class="cpp-literal">" ]"</span>
					  &lt;&lt; std::endl;
		}
		std::cout &lt;&lt; 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 &lt; 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&lt;<span class="cpp-keyword">double</span>&gt; Matrix3d;
<span class="cpp-keyword">typedef</span> Matrix3&lt;<span class="cpp-keyword">float</span>&gt; Matrix3f;
};<span class="cpp-comment">/* namespace Eckos*/</span>

<span class="cpp-directive">#endif</span> <span class="cpp-comment">/*MATRIX3_H_*/</span>

</pre></div><!–ENDSCRIPT–> 
Advertisement
So they should. Rotating about the x-axis by 90, then y-axis by 90 is the same position as y by 90, then x by 90.

Did you try other angles?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

???
.............|1 0 0|
Rx(90) = |0 0 -1|
.............|0 1 0|

.............|0 0 1|
Ry(90) = |0 1 0|
.............|-1 0 0|

..........................|0 0 1|......|0 1 0|
Rx(90) * Ry(90) = |1 0 0| != |0 0 -1| = Ry(90) * Rx(90)
..........................|0 1 0|......|-1 0 0|

[Edited by - Sbronz on June 21, 2008 6:31:56 PM]

This topic is closed to new replies.

Advertisement