Software Development/Graphics

6. Matrices

huiyu 2014. 10. 20. 23:36

행렬은 공간상의 한 점을 변환시킬 수 있는 수학적 도구이며, 행렬의 곱을 통해 여러 변환을 한꺼번에 적용할 수 있습니다.


1. 행렬 구조체

  - D3DMATRIX : 4행 4열을 가지는 구조체 변수

typedef struct _D3DMATRIX {
    union {
        struct {
            float        _11, _12, _13, _14;
            float        _21, _22, _23, _24;
            float        _31, _32, _33, _34;
            float        _41, _42, _43, _44;

        };
        float m[4][4];
    };
} D3DMATRIX;


 - D3DXMATRIX : D3DMATRIX를 상속한 행렬 클래스, 행렬에 관한 오버로딩 연산자를 가집니다.

#ifdef __cplusplus
typedef struct D3DXMATRIX : public D3DMATRIX
{
public:
    D3DXMATRIX() {};
    D3DXMATRIX( CONST FLOAT * );
    D3DXMATRIX( CONST D3DMATRIX& );
    D3DXMATRIX( CONST D3DXFLOAT16 * );
    D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14,
                FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24,
                FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34,
                FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 );


    // access grants
    FLOAT& operator () ( UINT Row, UINT Col );
    FLOAT  operator () ( UINT Row, UINT Col ) const;

    // casting operators
    operator FLOAT* ();
    operator CONST FLOAT* () const;

    // assignment operators
    D3DXMATRIX& operator *= ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator += ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator -= ( CONST D3DXMATRIX& );
    D3DXMATRIX& operator *= ( FLOAT );
    D3DXMATRIX& operator /= ( FLOAT );

    // unary operators
    D3DXMATRIX operator + () const;
    D3DXMATRIX operator - () const;

    // binary operators
    D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const;
    D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const;
    D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const;
    D3DXMATRIX operator * ( FLOAT ) const;
    D3DXMATRIX operator / ( FLOAT ) const;

    friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& );

    BOOL operator == ( CONST D3DXMATRIX& ) const;
    BOOL operator != ( CONST D3DXMATRIX& ) const;

} D3DXMATRIX, *LPD3DXMATRIX;

#else //!__cplusplus
typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX;
#endif //!__cplusplus


2. 행렬의 곱

 - D3DXMatrixMultiply

D3DXMATRIX* D3DXMatrixMultiply(
  _Inout_  D3DXMATRIX *pOut,
  _In_     const D3DXMATRIX *pM1,
  _In_     const D3DXMATRIX *pM2
);



3. 단위행렬

 임의의 n차 행렬A에 대해서 AE=EA=A를 만족하는 n차행렬 E를 단위행렬이라 하며, 

단위행렬은입니다. 주로 행렬을 초기화하는데 많이 사용

 

- D3DXMatrixIdentity

D3DXMATRIX* D3DXMatrixIdentity(
  _Inout_  D3DXMATRIX *pOut
);


-예제) 임의의행렬x단위행렬 = 임의의행렬임을 출력

#include "stdafx.h"
#include <d3dx9math.h>

int _tmain(int argc, _TCHAR* argv[])
{
	D3DXMATRIX matIdentity, matMatrix, matResult;
	D3DXMatrixIdentity(&matIdentity);

	for( int i=0; i<4; i++)
	{
		for(int j=0; j<4; j++)
		{
			matMatrix(i,j) = float(i*4+j+1);
		}
	}

	//곱셈
	D3DXMatrixMultiply(&matResult, &matMatrix, &matIdentity);
	matResult = matMatrix*matIdentity;
	for( int i=0; i<4; i++)
	{
		for(int j=0; j<4; j++)
		{
			printf("%7.1f", matMatrix(i, j));
		}
		printf("\n");
	}

	
	return 0;
}


4. 전치행렬

 행과 열을 바꾼행렬

 - D3DXMatrixTranspose

D3DXMATRIX* D3DXMatrixTranspose(
  _Inout_  D3DXMATRIX *pOut,
  _In_     const D3DXMATRIX *pM
);


 - 예제) 전치행렬 프로그램

#include "stdafx.h" #include <d3dx9math.h> int _tmain(int argc, _TCHAR* argv[]) { D3DXMATRIX matMatrix, matResult; for( int i=0; i<4; i++) { for(int j=0; j<4; j++) { matMatrix(i,j) = float(i*4+j+1); } } //전치행렬 D3DXMatrixTranspose(&matResult, &matMatrix); for(int i=0; i<4; i++) { for(int j=0; j<4; j++) { printf("%7.1f", matResult.m[i][j]); } printf("\n"); } return 0; }


5. 역행렬

A를 n차행렬, E를 단위행렬이라고 했을 때, AB = BA = E가 나오도록 하는 B행렬을 역행렬이라고 합니다.

 - D3DXMatrixInverse

D3DXMATRIX* D3DXMatrixInverse(
  _Inout_  D3DXMATRIX *pOut,
  _Inout_  FLOAT *pDeterminant,
  _In_     const D3DXMATRIX *pM
);

 

- 예제) 역행렬 프로그램

#include "stdafx.h"
#include <d3dx9math.h>

int _tmain(int argc, _TCHAR* argv[])
{
	D3DXMATRIX matMatrix, matResult;

	//1. 회전행렬
	D3DXMatrixRotationX(&matMatrix, 0.3f);

	printf("-----------회전행렬-----------------\n");
	for( int i=0; i<4; i++)
	{
		for(int j=0; j<4; j++)
		{
			printf("%7.1f", matMatrix(i, j));
		}
		printf("\n");
	}

	//2. Inverse
	printf("-----------Inverse-----------------\n");
	D3DXMatrixInverse(&matResult, NULL, &matMatrix);
	
	for(int i=0; i<4; i++)
	{
		for(int j=0; j<4; j++)
		{
			printf("%7.1f", matResult.m[i][j]);
		}
		printf("\n");
	}

	
	//3. Inverse
	printf("-----------Inverse-----------------\n");
	D3DXMatrixInverse(&matResult, NULL, &matResult);
	
	for(int i=0; i<4; i++)
	{
		for(int j=0; j<4; j++)
		{
			printf("%7.1f", matResult.m[i][j]);
		}
		printf("\n");
	}

	return 0;
}


6. 벡터와 행렬의 곱

 벡터 (x, y, z)를 공간상의 임의의 한 점인 (x', y', z')로 변환시킨다.

 - D3DXVec3Transform

3DXVECTOR4* D3DXVec3Transform(
  _Inout_  D3DXVECTOR4 *pOut,
  _In_     const D3DXVECTOR3 *pV,
  _In_     const D3DXMATRIX *pM
);


 - 예제) 벡터와 행렬의 곱

#include "stdafx.h" #include <d3dx9math.h> int _tmain(int argc, _TCHAR* argv[]) { //벡터와 행렬의 곱 D3DXMATRIX matMatrix; D3DXVECTOR3 v1(2.0f, 2.0f, 2.0f); D3DXVECTOR4 v2; D3DXMatrixIdentity(&matMatrix); matMatrix = -1 * matMatrix; for( int i=0; i<4; i++) { for(int j=0; j<4; j++) { printf("%7.1f", matMatrix(i, j)); } printf("\n"); } D3DXVec3Transform(&v2, &v1, &matMatrix); printf("----\n"); printf("변환결과 : %5.1f %5.1f %5.1f \n", v2.x, v2.y, v2.z, v2.w); return 0; }


728x90