www.pudn.com > ZFXMath-latest.zip > Matrix3x3.h


/// \file
///
/// \if DE
/// @brief TMatrix3x3
///
/// TMatrix3x3: Matrix für 2D oder Rotation für 3D
/// \else
/// @brief TMatrix3x3
///
/// TMatrix3x3: Matrix for 2D or rotation for 3D
/// \endif

#ifndef _ZFXMATH_INCLUDE_MATRIX3X3_H_
#define _ZFXMATH_INCLUDE_MATRIX3X3_H_

namespace ZFXMath
{
	/// \if DE
	/// @brief TMatrix3x3
	///
	/// TMatrix3x3: Matrix für 2D oder Rotation für 3D
	/// \else
	/// @brief TMatrix3x3
	///
	/// TMatrix3x3: Matrix for 2D or rotation for 3D
	/// \endif
	template
	class TMatrix3x3
	{

	public:

		union
		{
			T	m[9];
			struct
			{
				T _11; T _12; T _13;
				T _21; T _22; T _23;
				T _31; T _32; T _33;
			};
		};

		TMatrix3x3() 
		{
			(*this) = Identity();
		};

		TMatrix3x3(	const T& val ) 
		{ 
			_11 = _12 = _13 =
			_21 = _22 = _23 =
			_31 = _32 = _33 = val;
		}

		TMatrix3x3(	const T& _11, const T& _12, const T& _13,
					const T& _21, const T& _22, const T& _23,
					const T& _31, const T& _32, const T& _33 ) 
		{ 
			this->_11 = _11; this->_12 = _12; this->_13 = _13;
			this->_21 = _21; this->_22 = _22; this->_23 = _23;
			this->_31 = _31; this->_32 = _32; this->_33 = _33;
		}

		TMatrix3x3( const T& sx, const T& sy, const T& sz = (T)1.0 )
		{
			(*this) = TMatrix3x3( sx, 0.0, 0.0,
								  0.0, sy, 0.0,
								  0.0, 0.0, sz );
		}

		TMatrix3x3(	const T* _m )
		{
			memcpy( m, _m, sizeof( TMatrix3x3 ) );
		}

		TMatrix3x3(	const TMatrix3x3& _m )
		{
			memcpy( m, _m, sizeof( TMatrix3x3 ) );
		}

		TMatrix3x3( const T& rad, const T& scale, const TVector2D& p ) 
		{ 
			(*this) = Rotation2D( rad );
			Scale( scale );
			Translate( p );
		}
		

		TMatrix3x3(	const TVector3D& v1, const TVector3D& v2, const TVector3D& v3 ) 
		{
			_11 = v1.x; _12 = v1.y; _13 = v1.z;
			_21 = v2.x; _22 = v2.y; _23 = v2.z;
			_31 = v3.x; _32 = v3.y; _33 = v3.z;
		}
/*
		TMatrix3x3(	const TMatrix4x4& _m ) 
		{
			_11 = _m._11; _12 = _m._12; _13 = _m._13;
			_21 = _m._21; _22 = _m._22; _23 = _m._23;
			_31 = _m._31; _32 = _m._32; _33 = _m._33;
		}

		TMatrix3x3(	const TQuaternion& q ) 
		{
			T xx  = q.x + q.x;
			T yy  = q.y + q.y;
			T zz  = q.z + q.z;

			T wxx = q.w * xx;
			T wyy = q.w * yy;
			T wzz = q.w * zz;
			T xxx = q.x * xx;
			T xyy = q.x * yy;
			T xzz = q.x * zz;
			T yyy = q.y * yy;
			T yzz = q.y * zz;
			T zzz = q.z * zz;

			_11 = (T)1.0 - (yyy + zzz);
			_12 = xyy + wzz;
			_13 = xzz - wyy;

			_21 = xyy - wzz;
			_22 = (T)1.0 - (xxx + zzz);
			_23 = yzz + wxx;

			_31 = xzz + wyy;
			_32 = yzz - wxx;
			_33 = (T)1.0 - (xxx + yyy);
		}
*/

		/// \if DE
		/// @brief Caste in ein Array von T
		/// \else
		/// @brief Cast to an Array of T
		/// \endif
		operator T* ()	{ return m; }
		operator const T* () const { return m; }

		/// \if DE
		/// @brief Konstanter Zugriff über Index (Reihe, Spalte)
		/// \else
		/// @brief Const accessors by index (row, column)
		/// \endif
		T operator () ( const int i, const int j ) const
		{
			return m[ Check( i ) * 3 +  Check( j ) ];
		}

		/// \if DE
		/// @brief Nichtkonstanter Zugriff über Index (Reihe, Spalte)
		/// \else
		/// @brief Non-const accessors by index (row, column)
		/// \endif
		T& operator () ( const int i, const int j )
		{
			return m[ Check( i ) * 3 + Check( j ) ];
		}

		TMatrix3x3 operator + ( const TMatrix3x3& _m ) const { return TMatrix3x3(   _11 + _m._11, _12 + _m._12, _13 + _m._13,
																					_21 + _m._21, _22 + _m._22, _23 + _m._23,
																					_31 + _m._31, _32 + _m._32, _33 + _m._33 ); }
		TMatrix3x3 operator - ( const TMatrix3x3& _m ) const { return (*this) + _m.Negate(); }
		TMatrix3x3 operator * ( const TMatrix3x3& _m ) const { return Multiply( _m ); }
		TMatrix3x3 operator * ( const T& s ) const			 { return Scale( s ); }


		TMatrix3x3& operator += ( const TMatrix3x3& _m ) { *this = (*this) + _m; return (*this); }
		TMatrix3x3& operator -= ( const TMatrix3x3& _m ) { *this = (*this) - _m; return (*this); }
		TMatrix3x3& operator *= ( const TMatrix3x3& _m ) { *this = (*this) * _m; return (*this); }
		TMatrix3x3& operator *= ( const T& s )			 { *this = (*this) *  s; return (*this); }

		friend TVector3D operator * ( const TVector3D& v, const TMatrix3x3& m )
		{
			return TVector3D( TVector3D( m._11, m._21, m._31 ).DotProduct( v ),
								 TVector3D( m._12, m._22, m._32 ).DotProduct( v ),
								 TVector3D( m._13, m._23, m._33 ).DotProduct( v ) ); 
		}
/*
		friend TQuaternion operator * ( const TQuaternion& q, const TMatrix3x3& m )
		{
			return TQuaternion( );
		}

		friend TMatrix3x3 operator * ( const TMatrix3x3& m, const TQuaternion& q )
		{
			return m * TMatrix3x3( q );
		}
*/
		static TMatrix3x3 Zero()
		{
			return TMatrix3x3( 0.0 );
		}

		static TMatrix3x3 Identity()
		{
			return TMatrix3x3(  1.0, 0.0, 0.0,
								0.0, 1.0, 0.0,
								0.0, 0.0, 1.0 );
		}

		/// \if DE
		/// @brief skaliert die Matrix
		/// \else
		/// @brief scales the matrix
		/// \endif
		TMatrix3x3& Scale( const T& s )
		{
			_11 *= s; _12 *= s; _13 *= s; 
			_21 *= s; _22 *= s; _23 *= s; 
			_31 *= s; _32 *= s; _33 *= s;

			return (*this);
		}

		/// \if DE
		/// @brief skaliert die Matrix
		/// \else
		/// @brief scales the matrix
		/// \endif
		TMatrix3x3& Scale( const T& sx, const T& sy, const T& sz = (T)1.0 )
		{
			_11 *= sx; _12 *= sy; _13 *= sz; 
			_21 *= sx; _22 *= sy; _23 *= sz; 
			_31 *= sx; _32 *= sy; _33 *= sz;

			return (*this);
		}

		/// \if DE
		/// @brief skaliert die Matrix
		/// \else
		/// @brief scales the matrix
		/// \endif
		TMatrix3x3& Scale( const TVector3D& sv )
		{
			return Scale( sv.x, sv.y, sv.z );
		}

/*
		TMatrix3x3& SkewX( const T& rad )
		{
			return (*this);
		}
		TMatrix3x3& SkewY( const T& rad )
		{
			return (*this);
		}
*/

		/// \if DE
		/// @brief Erstellt eine Matrix die um p transliert ist
		/// \else
		/// @brief Creates a matrix which translates by p
		/// \endif
		static TMatrix3x3 Translation( const TVector2D& p )
		{
			return Translation( p.x, p.y );
		}

		/// \if DE
		/// @brief Erstellt eine Matrix die um P(x,y) transliert ist
		/// \else
		/// @brief Creates a matrix which translates by P(x,y)
		/// \endif
		static TMatrix3x3 Translation( const T& x, const T& y )
		{
			TMatrix3x3 newM = TMatrix3x3::Identity();
			newM._31 = x;
			newM._32 = y;

			return newM;
		}

		/// \if DE
		/// @brief Transliert die Matrix um p
		/// \else
		/// @brief Translates the matrix by p
		/// \endif
		TMatrix3x3& Translate( const TVector2D& p )
		{
			return Translate( p.x, p.y );
		}

		/// \if DE
		/// @brief Transliert die Matrix um P(x,y)
		/// \else
		/// @brief Translates the matrix by P(x,y)
		/// \endif
		TMatrix3x3& Translate( const T& x, const T& y )
		{
			_31 += x;
			_32 += y;
			return (*this);
		}

		/// \if DE
		/// @brief Multipliziert zwei matrizen miteineander
		/// \else
		/// @brief Multiplies two matrices
		/// \endif
		TMatrix3x3 Multiply( const TMatrix3x3& _m ) const
		{
			TMatrix3x3 newM = TMatrix3x3::Zero();

			for ( int i = 0; i < 3; i++ )
			{
				for ( int j = 0; j < 3; j++ )
				{
					for ( int k = 0; k < 3; k++ )
					{
						newM.m[i * 3 + j] += m[i * 3 + k] * _m.m[k * 3 + j];
					}
				}
			}

			return newM;
		}

		/// \if DE
		/// @brief Erstellt eine Matrix die um X rotiert
		/// \else
		/// @brief Creates a matrix which rotates around X
		/// \endif
		static TMatrix3x3 RotationX( const T& rad )
		{
			T sin, cos;

			SinCos( rad, sin, cos );  // Determine sin and cos of angle

			return TMatrix3x3( 1.0, 0.0, 0.0,
							   0.0, cos, sin,
							   0.0, -sin, cos );
		}

		/// \if DE
		/// @brief Rotiert die Matrix um X
		/// \else
		/// @brief Rotates the matrix around X
		/// \endif
		TMatrix3x3& RotateX( const T& rad )
		{
			return (*this) *= RotationX( rad );
		}

		/// \if DE
		/// @brief Erstellt eine Matrix die um Y rotiert
		/// \else
		/// @brief Creates a matrix which rotates around Y
		/// \endif
		static TMatrix3x3 RotationY( const T& rad )
		{
			T sin, cos;

			SinCos( rad, sin, cos );  // Determine sin and cos of angle

			return TMatrix3x3( cos, 0.0, -sin,
							   0.0, 1.0, 0.0,
							   sin, 0.0, cos );
		}

		/// \if DE
		/// @brief Rotiert die Matrix um Y
		/// \else
		/// @brief Rotates the matrix around Y
		/// \endif
		TMatrix3x3& RotateY( const T& rad )
		{
			return (*this) *= RotationY( rad );
		}

		/// \if DE
		/// @brief Erstellt eine Matrix die um Z rotiert
		/// \else
		/// @brief Creates a matrix which rotates around Z
		/// \endif
		static TMatrix3x3 RotationZ( const T& rad )
		{
			T sin, cos;

			SinCos( rad, sin, cos );  // Determine sin and cos of angle

			return TMatrix3x3( cos, sin, 0.0,
							  -sin, cos, 0.0,
							   0.0, 0.0, 1.0 );
		}

		/// \if DE
		/// @brief Rotiert die Matrix um Z 
		/// \else
		/// @brief Rotates the matrix around Z
		/// \endif
		TMatrix3x3& RotateZ( const T& rad )
		{
			return (*this) *= RotationZ( rad );
		}

		/// \if DE
		/// @brief Erstellt eine 2D-Rotationsmatrix
		/// \else
		/// @brief Creates a 2D rotation matrix
		/// \endif
		static TMatrix3x3 Rotation2D( const T& rad )
		{
			return RotationZ( rad );
		}

		/// \if DE
		/// @brief Rotiert die Matrix im 2D-Raum
		/// \else
		/// @brief Rotates the matrix in 2D-Space
		/// \endif
		TMatrix3x3& Rotate2D( const T& rad )
		{
			return (*this) *= Rotation2D( rad );
		}


		/// \if DE
		/// @brief Gibt die transponierte Matrix zurück
		/// \else
		/// @brief returns the transposed matrix
		/// \endif
		TMatrix3x3 Transpose() const
		{
			return TMatrix3x3( _11, _21, _31,
							   _12, _22, _32,
							   _13, _23, _33 );
		}

		/// \if DE
		/// @brief Gibt die negierte Matrix zurück
		/// \else
		/// @brief returns the negated matrix
		/// \endif
		TMatrix3x3 Negate() const
		{
			return TMatrix3x3( -_11, -_12, -_13,
							   -_21, -_22, -_23,
							   -_31, -_32, -_33 );
		}

		/// \if DE
		/// @brief wechselt die Matrix von LeftHanded auf RightHanded und umgekehrt
		/// \else
		/// @brief switches between left handed and right handed and vice versa
		/// \endif
		TMatrix3x3 GetSwitchedHand() const
		{
			TMatrix3x3 newM( Transpose() );
			newM._32 = -newM._32;
			newM._23 = -newM._23;
			newM._13 = -newM._13;
			newM._31 = -newM._31;

			return newM;
		}

	private:
		inline int Check( const int index ) const
		{
			// Check bounds in debug build
			assert( index >= 0 && index < 3 );

			return index;
		}

		
	};
}

#endif //_ZFXMATH_INCLUDE_MATRIX3X3_H_