사원수(quaternian)

 

쿼터니언은 복소수의 확장으로 i, j, k 3개의 허수와 w, x, y, z 4개의 실수부로 이루어져 있다.

즉 하나의 스칼라와 3개의 벡터 ==> 4개의 구성 요소로 이루어진 복소수를 말한다.

허수 i, j, k는 i * i = -1의 성질을 가진다.

 = w + xi + yj + zk
 

= sq + vq

 

 = (sq , vq)

 

 = [ w , (x, y, z) ]

여기서 w는 스칼라 v = (x, y, z)는 벡터이다.

쿼터니언 크기  ||q|| = Norm(q) = sqrt(w2 + x2 + y2 + z2)

단위 쿼터니언 성질  w2 + x2 + y2 + z2 = 1

단위 쿼터니언은 (x, y, z)요소를 임의의 축, w요소를 회전 각도로 하여 4차원 공간에 표현 할 수 있다.

그림으로 간단하게 표현 하면 벡터 축 A를 중심으로 회전하는 θ는

 

사원수를 이용한 벡터 회전 변환

벡터 p를 사원수 q로 회전할 때 공식과 행렬에 대한 변환은 다음과 같다.(증명은... 어려워 생략)

 

 =

|
|
|
|
|
|

1 - 2Y2 - 2Z2

2XY + 2ZW

2XZ - 2YW

2XY - 2ZW

1 - 2X2 - 2Z2

2YZ + 2XW

2XZ + 2YW

2YZ - 2XW

1 - 2X2 - 2Y2

|
|
|
|
|
|

 

쿼트니언을 행렬 변환하는 함수

//-----------------------------------------------------------------------------

//예전 다이렉트X 버전에 d3dmath.cpp 파일에 있는 소스이다.

//-----------------------------------------------------------------------------

VOID D3DMath_MatrixFromQuaternion( D3DMATRIX& mat, FLOAT x, FLOAT y, FLOAT z, FLOAT w )

{

    FLOAT xx = x*x; FLOAT yy = y*y; FLOAT zz = z*z;

    FLOAT xy = x*y; FLOAT xz = x*z; FLOAT yz = y*z;

    FLOAT wx = w*x; FLOAT wy = w*y; FLOAT wz = w*z;

 

    mat._11 = 1 - 2 * ( yy + zz );

    mat._12 =    2 * ( xy - wz );

    mat._13 =    2 * ( xz + wy );

 

    mat._21 =    2 * ( xy + wz );

    mat._22 = 1 - 2 * ( xx + zz );

    mat._23 =    2 * ( yz - wx );

 

    mat._31 =    2 * ( xz - wy );

    mat._32 =    2 * ( yz + wx );

    mat._33 = 1 - 2 * ( xx + yy );

 

    mat._14 = mat._24 = mat._34 = 0.0f;

    mat._41 = mat._42 = mat._43 = 0.0f;

    mat._44 = 1.0f;

}

 

행열을 쿼트니언으로 변환하는 함수

VOID D3DMath_QuaternionFromMatrix( FLOAT& x, FLOAT& y, FLOAT& z, FLOAT& w, D3DMATRIX& mat )

{

    if( mat._11 + mat._22 + mat._33 > 0.0f )

    {

        FLOAT s = (FLOAT)sqrt( mat._11 + mat._22 + mat._33 + mat._44 );

 

        x = (mat._23-mat._32) / (2*s);

        y = (mat._31-mat._13) / (2*s);

        z = (mat._12-mat._21) / (2*s);

        w = 0.5f * s;

    }

    else

    {

 

 

    }

    FLOAT xx = x*x; FLOAT yy = y*y; FLOAT zz = z*z;

    FLOAT xy = x*y; FLOAT xz = x*z; FLOAT yz = y*z;

    FLOAT wx = w*x; FLOAT wy = w*y; FLOAT wz = w*z;

 

    mat._11 = 1 - 2 * ( yy + zz );

    mat._12 =    2 * ( xy - wz );

    mat._13 =    2 * ( xz + wy );

 

    mat._21 =    2 * ( xy + wz );

    mat._22 = 1 - 2 * ( xx + zz );

    mat._23 =    2 * ( yz - wx );

 

    mat._31 =    2 * ( xz - wy );

    mat._32 =    2 * ( yz + wx );

    mat._33 = 1 - 2 * ( xx + yy );

 

    mat._14 = mat._24 = mat._34 = 0.0f;

    mat._41 = mat._42 = mat._43 = 0.0f;

    mat._44 = 1.0f;

}

 

 

 

[펌]사원수 이해하기