bate's blog

調べたこと実装したことなどを取りとめもなく書きます。

再び読む気になれないコードに

以前作った行列クラスはこんな感じ。

class Matrix44
{
public:
	float m_11, m_12, m_13, m_14,
	      m_21, m_22, m_23, m_24,
	      m_31, m_32, m_33, m_34,
	      m_41, m_42, m_43, m_44;

	Matrix44( float in11=1, float in12=0, float in13=0, float in14=0,
                  float in21=0,float in22=1, float in23=0, float in24=0,
		 float in31=0, float in32=0, float in33=1, float in34=0,
                 float in41=0, float in42=0, float in43=0, float in44=1 )
	:m_11(in11), m_12(in12), m_13(in13), m_14(in14), m_21(in21), m_22(in22), m_23(in23), m_24(in24),
	 m_31(in31), m_32(in32), m_33(in33), m_34(in34), m_41(in41), m_42(in42), m_43(in43), m_44(in44)
	{ }

	// 加算
	Matrix44 operator +( const Matrix44& mat ) const
	{
		return Matrix44( this->m_11+mat.m_11, this->m_12+mat.m_12, this->m_13+mat.m_13, this->m_14+mat.m_14,
				 this->m_21+mat.m_21, this->m_22+mat.m_22, this->m_23+mat.m_23, this->m_24+mat.m_24,
				 this->m_31+mat.m_31, this->m_32+mat.m_32, this->m_33+mat.m_33, this->m_34+mat.m_34,
				 this->m_41+mat.m_41, this->m_42+mat.m_42, this->m_43+mat.m_43, this->m_44+mat.m_44 );
	}

	// 減算
	Matrix44 operator -( const Matrix44& mat ) const
	{
		return Matrix44( this->m_11-mat.m_11, this->m_12-mat.m_12, this->m_13-mat.m_13, this->m_14-mat.m_14,
				 this->m_21-mat.m_21, this->m_22-mat.m_22, this->m_23-mat.m_23, this->m_24-mat.m_24,
				 this->m_31-mat.m_31, this->m_32-mat.m_32, this->m_33-mat.m_33, this->m_34-mat.m_34,
				 this->m_41-mat.m_41, this->m_42-mat.m_42, this->m_43-mat.m_43, this->m_44-mat.m_44 );
	}

	// スカラ乗算
	Matrix44 operator *( const float f ) const
	{
		return Matrix44( this->m_11*f, this->m_12*f, this->m_13*f, this->m_14*f,
				 this->m_21*f, this->m_22*f, this->m_23*f, this->m_24*f,
				 this->m_31*f, this->m_32*f, this->m_33*f, this->m_34*f,
				 this->m_41*f, this->m_42*f, this->m_43*f, this->m_44*f );
	}

	// スカラ除算
	Matrix44 operator /( const float f ) const
	{
		return Matrix44( this->m_11/f, this->m_12/f, this->m_13/f, this->m_14/f,
				 this->m_21/f, this->m_22/f, this->m_23/f, this->m_24/f,
				 this->m_31/f, this->m_32/f, this->m_33/f, this->m_34/f,
				 this->m_41/f, this->m_42/f, this->m_43/f, this->m_44/f );
	}

	// 行列同士の積
	Matrix44 operator *( const Matrix44& mat ) const
	{
		return Matrix44( this->m_11*mat.m_11 + this->m_12*mat.m_21 + this->m_13*mat.m_31 + this->m_14*mat.m_41,
				 this->m_11*mat.m_12 + this->m_12*mat.m_22 + this->m_13*mat.m_32 + this->m_14*mat.m_42,
				 this->m_11*mat.m_13 + this->m_12*mat.m_23 + this->m_13*mat.m_33 + this->m_14*mat.m_43,
				 this->m_11*mat.m_14 + this->m_12*mat.m_24 + this->m_13*mat.m_34 + this->m_14*mat.m_44,
				 this->m_21*mat.m_11 + this->m_22*mat.m_21 + this->m_23*mat.m_31 + this->m_24*mat.m_41,
				 this->m_21*mat.m_12 + this->m_22*mat.m_22 + this->m_23*mat.m_32 + this->m_24*mat.m_42,
				 this->m_21*mat.m_13 + this->m_22*mat.m_23 + this->m_23*mat.m_33 + this->m_24*mat.m_43,
				 this->m_21*mat.m_14 + this->m_22*mat.m_24 + this->m_23*mat.m_34 + this->m_24*mat.m_44,
				 this->m_31*mat.m_11 + this->m_32*mat.m_21 + this->m_33*mat.m_31 + this->m_34*mat.m_41,
				 this->m_31*mat.m_12 + this->m_32*mat.m_22 + this->m_33*mat.m_32 + this->m_34*mat.m_42,
				 this->m_31*mat.m_13 + this->m_32*mat.m_23 + this->m_33*mat.m_33 + this->m_34*mat.m_43,
				 this->m_31*mat.m_14 + this->m_32*mat.m_24 + this->m_33*mat.m_34 + this->m_34*mat.m_44,
				 this->m_41*mat.m_11 + this->m_42*mat.m_21 + this->m_43*mat.m_31 + this->m_44*mat.m_41,
				 this->m_41*mat.m_12 + this->m_42*mat.m_22 + this->m_43*mat.m_32 + this->m_44*mat.m_42,
				 this->m_41*mat.m_13 + this->m_42*mat.m_23 + this->m_43*mat.m_33 + this->m_44*mat.m_43,
				 this->m_41*mat.m_14 + this->m_42*mat.m_24 + this->m_43*mat.m_34 + this->m_44*mat.m_44 );
	}

	Vector operator *( const Vector& vec ) const
	{
		return Vector( this->m_11*vec.x + this->m_12*vec.y + this->m_13*vec.z,
			       this->m_21*vec.x + this->m_22*vec.y + this->m_23*vec.z,
			       this->m_31*vec.x + this->m_32*vec.y + this->m_33*vec.z );
	}
};



//---------------------------------------------------------
// プロトタイプ宣言
//---------------------------------------------------------

// 平行移動に変換
Matrix44 Translate( const float x, const float y, const float z );

// 平行移動に変換
Matrix44 Translate( const Vector& v );

// 回転行列に変換
Matrix44 Rotate( char axis, float rad );

// YawPitchRollを指定して回転行列を取得
Matrix44 YawPitchRoll( const float y, const float x, const float z );

// 拡大・縮小行列に変換
Matrix44 Scale( const float x, const float y, const float z );

// 角度をラジアンに変換
float DegToRad( float deg );

上記は平均的なコードだと思います。
今回は配列でやっている。
見るも無残な汚いコードです。

// Matrix.h

#ifndef __MATRIX_H__
#define __MATRIX_H__

#include <iostream>

// 行列テンプレート
template<int M, int N, typename T>
class TMatrix
{
private:
	T m_elements[M][N];
public:
	TMatrix()
	{ }
	TMatrix( T (*array)[N] )
	{
		for( int i = 0; i < M; ++i )
			for( int j = 0; j < N; ++j )
				m_elements[i][j] = array[i][j];
	}

	~TMatrix()
	{ }

	T GetMatrix( int index_1, int index_2 );
	T* GetMatrix();
	void GetRow( int index, T *r_out );	// 行
	void GetColumn( int index, T *c_out );	// 列
	void SetMatrix( int index_1, int index_2, T input );
	void Disp();

	T InnerProduct( TMatrix<M,N,T> t, int l, int r );

	TMatrix<M, N, T>& operator=( TMatrix<M,N,T> t )
	{
		for( int i = 0; i < M; ++i )
			for( int j = 0; j < N; ++j )
				this->m_elements[i][j] = t.GetMatrix( i, j );

		return *this;
	}

	TMatrix<M, N, T> operator+( TMatrix<M,N,T> t )
	{
		T array[M][N];
		for( int i = 0; i < M; ++i )
			for( int j = 0; j < N; ++j )
				array[i][j] = this->m_elements[i][j] + t.GetMatrix( i, j );
		
		return TMatrix<M,N,T>( array );
	}

	TMatrix<M, N, T> operator-( TMatrix<M,N,T> t )
	{
		T array[M][N];
		for( int i = 0; i < M; ++i )
			for( int j = 0; j < N; ++j )
				array[i][j] = this->m_elements[i][j] - t.GetMatrix( i, j );

		return TMatrix<M,N,T>( array );
	}
	
	TMatrix<M,N,T> operator*( TMatrix<M,N,T> t )
	{
		T array[M][N] = { 0 };
		int index_1 = 0, index_2 = 0;
		for( int i = 0; i < M; ++i )
		{
			for( int j = 0; j < N; ++j )
			{
				array[i][j] = this->InnerProduct( t, index_1, index_2 );
				++index_2;
			}
			++index_1;
			index_2 = 0;
		}

		return TMatrix( array );
	}
};

template<int M, int N, typename T> T TMatrix<M, N, T>::GetMatrix( int index_1, int index_2 )
{
	return m_elements[index_1][index_2];
}

template<int M, int N, typename T> T* TMatrix<M,N,T>::GetMatrix()
{
	return m_elements;
}

template<int M, int N, typename T> void TMatrix<M,N,T>::GetRow( int index, T *r_out )
{
	// index行を返す
	//T array[N] = { 0 };
	for( int i = 0; i < N; ++i )
	{
		r_out[i] = this->m_elements[index][i];
		std::cout << r_out[i] << " ";
	}
	std::cout << std::endl;

	//r_out = array;
}

template<int M, int N, typename T> void TMatrix<M,N,T>::GetColumn( int index, T *c_out )
{
	// index列を返す
	//T array[M] = { 0 };
	for( int i = 0; i < M; ++i )
	{
		c_out[i] = this->m_elements[i][index];
		std::cout << c_out[i] << " ";
	}
	std::cout << std::endl;

	//c_out = array;
}

template<int M, int N, typename T> void TMatrix<M, N, T>::SetMatrix( int index_1, int index_2, T input )
{
	elements[index_1][index_2] = input;
}

template<int M, int N, typename T> T TMatrix<M,N,T>::InnerProduct( TMatrix<M,N,T> t, int l, int r )
{
	T l_array[N] = { 0 };
	this->GetRow( l, l_array );
	T r_array[M] = { 0 };
	t.GetColumn( r, r_array );
	for( int i = 0; i < 2; ++i )
		std::cout << "l:" << l_array[i] << std::endl << "r:" << r_array[i] << std::endl;
	T ret = 0;
	if( M < N )
	{
		for( int i = 0; i < M; ++i )
			ret += l_array[i]*r_array[i];
	}
	else
	{
		for( int i = 0; i < N; ++i )
			ret += l_array[i]*r_array[i];
	}

	std::cout << ret << std::endl;
	return ret;
}



template<int M, int N, typename T> void TMatrix<M, N, T>::Disp()
{
	for( int i = 0; i < M; ++i )
	{
		for( int j = 0; j < N; ++j )
			std::cout << m_elements[i][j] << " ";
		std::cout << std::endl;
	}
}


#endif	// __MATRIX_H__