Jump to content
  • Advertisement
Sign in to follow this  
Eckos

Rotation problem

This topic is 3827 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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[i + 3] << ", " << mat[i + 6] << " ]"
					  << std::endl;
		}
		std::cout << std::endl;
	}

	//! Pointer to the Matrix array
	/*!
	Returns the array for easy access to the Matrix array.
	\return Pointer to the mat Matrix array
	*/
	MAT3_INLINE const Real* ptr()
	{
		return mat.data();
	}

	//! Matrix size
	/*!
	Length of the mat Matrix array
	\return Length of the Matrix array
	*/
	MAT3_INLINE size_t size()
	{
		return mat.size();
	}

	//! Determinant of the current Matrix
	/*!
	Finds the determinant of the Matrix
	\return Determinant value
	*/
	MAT3_INLINE Real determinant()
	{
		return determinant(mat[0], mat[3], mat[6],
		                   mat[1], mat[4], mat[7],
		                   mat[2], mat[5], mat[8]);
	}

	//! Determinant of the 2x2 Matrix
	/*!
	Finds the determinant of the 2x2 Matrix (minor)
	\return Determinant value
	*/
	MAT3_INLINE Real determinant(Real a, Real b,
	                             Real c, Real d)
	{
		return a * b - c * d;
	}

	//! Determinant of the 3x3 Matrix
	/*!
	Finds the determinant of the 3x3 Matrix(minor)
	*/
	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);
		return +a1 - b1 + c1;
	}

	//! Finds the inverse of this Matrix
	/*!
	Determines the inverse of this Matrix
	\param inverse Out parameter that if true it is inversed, false if not.
	\return The inverse
	*/
	MAT3_INLINE Matrix3 inverse(bool *inverse = false)
	{
		Matrix3 tmpMat = Matrix3();
		tmpMat.mat[0] = determinant(mat[4], mat[8], mat[7], mat[5]);
		tmpMat.mat[1] = -determinant(mat[3], mat[8], mat[6], mat[5]);
		tmpMat.mat[2] = determinant(mat[3], mat[7], mat[6], mat[4]);

		tmpMat.mat[3] = -determinant(mat[1], mat[8], mat[7], mat[2]);
		tmpMat.mat[4] = determinant(mat[0], mat[8], mat[6], mat[2]);
		tmpMat.mat[5] = -determinant(mat[0], mat[7], mat[6], mat[1]);

		tmpMat.mat[6] = determinant(mat[1], mat[5], mat[4], mat[2]);
		tmpMat.mat[7] = -determinant(mat[0], mat[5], mat[3], mat[2]);
		tmpMat.mat[8] = determinant(mat[0], mat[4], mat[3], mat[1]);

		tmpMat.transpose();

		Real det = determinant();
		if(det == 0)
		{
			*inverse = false;
			return Matrix3::identity();
		}

		for(unsigned i = 0; i < mat.size(); ++i)
		{
			tmpMat.mat /= det;
		}

		*inverse = true;
		return tmpMat;
	}
}; /*class Matrix3*/
typedef Matrix3<double> Matrix3d;
typedef Matrix3<float> Matrix3f;
};/* namespace Eckos*/

#endif /*MATRIX3_H_*/

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
???
.............|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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!