[ Goal ] DirectXMath 라이브러리 가 제공하는 여러 변환 행렬 함수 숙지


1. 변환

  • 3차원 그래픽은 물체의 외부 표면을 근사하는 일단의 삼각형들로 물체를 표현한다.
  • 이러한 삼각형들에 대해 이동변환, 회전변환, 비례변환 등을 통해 3차원 그래픽 구조를 움직이게 한다.

 

  • 선형 변환
    • 아래와 같은 성질이 성립되면 선형 변환이라 부른다.
    • 이를 왜 맨처음에 소개를 하냐면 선형변환이 보장 되어야 우리가 변환에 대한 행렬을 구할수 있기 때문이다.

선형 변환의 성질 ( 필요충분 조건 )
선형 변환을 통해 변환행렬을 구하는 방법

 

 

 

  • 비레 변환
    • 물체의 크기를 바꾸는 효과를 낸다.
    • 비례 변환 또한 선형 변환이므로 변환 행렬이 존재한다. 변환 행렬 구하는 방법은 위의 식을 통해 구할수 있다.

 

비례 변환의 정의

 

비례 행렬
비례 행렬의 역

 

  • 회전 변환
    • 벡터 v를 축 n에 대하여 회전하고 싶을때 사용되는 변환이다.
    • 이러한 변환에서 회전각은 n의 반대방향 기준으로 시계방향으로 측정된다.
    • 회전 변환 행렬의 특징은 역행렬이 전치행렬인 것이다.
      • 이러한 행렬을 정규직교 행렬이라 한다.
      • 정규직교 행렬은 각 행벡터의 크기가 1이며 각 행벡터 서로가 직교인 특징을 가진다.

 

회전 변환의 정의
회전 변환 행렬 이떄 x,y,z는 회전 기준 축의 단위벡터
회전변환 역행렬 = 전치행렬
순서대로 회전축이 x일때, y일때, z일떄의 회전 변환 행렬 ( 4x4 행렬 처럼 보이지만 계산과정을 잘 생각해보면 단순 3x3 행렬과 같다. )

 

 

 

 

 


2. 아핀변환

 

 

2.1 동차 좌표

  • 1x3 의 행렬로 벡터와 점을 표기하기에는 벡터값과 정점을 구분하는데 어려움이 있다. 이를 해결하기 위해 1x4 행렬로 벡터값과 정점을 표현한 것이 동차 좌표이다.
    • 벡터 : ( x, y, z, 0 ) -> 벡터끼리의 합은 벡터이므로 4번째 요소를 0
    • 정점 : ( x, y, z, 1 ) -> 벡터 + 정점은 정점이므로 4번째 요소를 1 ( 정점 + 정점은 수행 불가 )

 

2.2 아핀변환의 정의와 행렬 표현

  • 아핀 변환은 단순히 선형 변환 후 이동벡터를 더한 것이다.

아핀 변환 정의

  • 3x3 행렬이 아닌 4x4행렬로 나타내면 더욱 간단히 나타낼 수 있다. 이를 아핀변환의 행렬 표현이라 한다.
  • 주목할 점은 마지막 성분 계산시 내적하는 벡터가 (0,0,0,1) 이라는 점이다. 이는 아핀변환시 벡터는 벡터로 정점은 정점으로 결과값이 나온다는 말이다.

아핀 변환 행렬

 

 

2.3 이동변환

  • 위의 아핀변환 행렬에서 조금만 생각하면 이동행렬이 무엇일지 예상이 간다.
  • 이동행렬은 변환없이 이동벡터만 더하는 것으로 생각할수 있다.
  • 당연히 역행렬은 -T이다.

이동 변환의 행렬표현

 

 

 


3. 좌표계 변환

  • 좌표계 변환은 간단한 예시를 들자면 섭씨온도와 화씨온도에 대한 변환이라 생각하면 된다.
  • 즉 기준이 되는 값을 그리고 증가 감소 방향을 바꾸는 것이다.
  • 이는 물체의 형태가 바뀌는 변환이 아닌것을 유의하자. ( 물론 크기가 비례해서 증가 감소가 할수 있지만 완전히 다른 형태로 바뀔수는 없다. 위상수학을 배웠다면! 쉽게! 이해! 가능! 물론 안배웠어도 쉽게 이해 가능 )

 

3.1 벡터의 좌표계 변환

  • 벡터는 기준점이 원점인것을 기억하자.
  • A좌표계 안에 있는 p 벡터는 B좌표계에서 어떻게 표현하는지 알고 싶다면 아래의 식을 사용하면 된다.
    • A좌표계의 단위 벡터 : u, v
    • B좌표계의 단위 벡터 : x, y
    • A좌표계에서의 p벡터 값 : ( a, b ) = a*u + b*v
    • B좌표계에서의 p벡터 값 : a*x + b*y
    • 단순히 벡터를 단위벡터의 선형결합으로 나타낸 후 곱해진 단위 벡터를 바꾸고 싶은 좌표계로 바꾸면 된다.

 

 

3.2 점의 좌표계 변환

  • 벡터와 달리 점은 위치 값이 있다. 이를 생각해보면 점의 위치는 좌표계의 원점 값 + 이동벡터라 생각하면 된다.
  • A좌표계 안에 있는 점p 는 B좌표계에서 어떻게 표현하는지 알고 싶다면 아래의 식을 사용하면 된다.
    • A좌표계의 단위 벡터 : u, v
    • B좌표계의 단위 벡터 : x, y
    • A좌표계에서의 점p 값 : ( a, b ) = a*u + b*v + Qa ( Qa는 A좌표계에서 측정한 A좌표계 원점의 좌표값이다. )
    • B좌표계에서의 p벡터 값 : a*x + b*y + Qb ( Qb는 A좌표계에서 측정한 B좌표계 원점의 좌표값이다. )
    • 벡터의 좌표계 변환에다 좌표계의 원점 위치를 더해주면 되는것이다. 이때 더해지는 Qa Qb값이 어떤 좌표계를 기준으로 측정되어있는지 주의하자.

 

 

3.3 좌표계 변환의 행렬

  • 위의 내용을 다시 생각해보면 행렬 표현으로 아래와 같이 표현할수 있다.
  • 벡터의 값은 (x, y, z ,0 ) 과 같은 형식으로 되어있으므로 결과의 4번째 더해지는 값은 항상 0이 된다. 또한 점값은 4번째 더해지는 값이 Qb가 됨을 알수 있다.

각 u, v, w 는 변환할 좌표계의 단위 벡터이다. Qb는 변환할 좌표계의 원점의 위치이다.

  • 또한 좌표변환 행렬이 A->B로 바꾸는 행렬이면 역행렬은 B->A로 변환하는 행렬이다.
    • 물론 역행렬이 존재하지 않는 좌표변환 행렬이 존재할수 있지만 일반적으로 다루지 않는다.

 

 

 

3.4 능동적 변환 행렬과 좌표계 변환 행렬

  • 좌표계변환 행렬과 아핀변환 행렬을 확인해보면 서로 모양이 같다는것을 확인 할 수 있다.
  • 또한 수학적으로 동치 관계이다. ( 즉 둘이 서로 같은거라는 말 )
  • 이 두가지를 모두 배우는 이유는 아래의 예시를 통해 이해하자.
    • 현재 좌표계가 카메라의 좌표계이고 어떤 물체를 플레이어 캐릭터 주변을 회전하게 하고 싶을때 
    • 능동적변환 즉 아핀변환을 사용하면 할수는 있지만 코드 이해하기 쉽지 않다.
      • 회전 -> 플레이어쪽으로 이동
    • 하지만 좌표계 변환을 하면 코드를 쉽게 이해할수 있다.
      • 좌표계 플레이어로 변환 -> 회전
  • 이와같이 모든 변환 행렬은 두 방법을 통해 나타낼수 있다. 하지만 경우에 따라서 어떠한 행렬이 좀더 이해하기 쉬운지 또는 계산하기 편한지를 확인해야한다.

 

 

 

 


4. DirectXMath 에서의 변환 행렬 함수들

  • 아래와 같은 DirectXMath 라이브러리에 관련 함수들이 존재
// 비례행렬 생성
XMMATRIX XM_CALLCONV XMMAtrixScaling(
	float ScaleX,
    float SclaeY,
    float XcaleZ);                  // 각 매개변수는 비례계수이다.
    
    
// 벡터의 성분들로 비례행렬 생성
XMMATRIX XM_CALLCONV XMMatrixScalingFromVector(
	FXMVECTOR Scale);               // 매개변수 : (sx, sy, sz, 0)


// x축에 대한 회전행렬 Rx 생성
XMMATRIX XM_CALLCONV XMMatrixRotationX(
	float Angle);                   // X축에 대해 Angle만큼 회전하는 변환행렬 생성
    
    
// y축에 대한 회전행렬 Ry 생성
XMMATRIX XM_CALLCONV XMMatrixRotationY(
	float Angle);                   // Y축에 대해 Angle만큼 회전하는 변환행렬 생성
    
    
// z축에 대한 회전행렬 Rz 생성
XMMATRIX XM_CALLCONV XMMatrixRotationZ(
	float Angle);                   // Z축에 대해 Angle만큼 회전하는 변환행렬 생성
    
    
// 임의의축에 대한 회전행렬 Rn 생성
XMMATRIX XM_CALLCONV XMMatrixRotationN(
	FXMVECTOR Axis                  // 회전축의 벡터 (ex. x축 : (1,0,0,0) )
    float Angle);                   // X축에 대해 Angle만큼 회전하는 변환행렬 생성
    
    
// 이동행렬 T 생성
XMMATRIX XM_CALLCONV XMMatrixTranslation(
	float OffsetX,
    float OffsetY,
    float OffsetZ);                 // 매개변수는 각 이동 오프셋이다.
    

// 벡터를 이용한 이동행렬 T 생성
XMMATIRX XM_CALLCONV XMMatrixTranslation(
	FXMVECTOR Offset);              // ( offsetX, offsetY, offsetZ, 0 )
    
    
// 벡터와 행렬의 곱 함수 -> 결과 점 ( =  벡터 * 행렬,  != 행렬 * 벡터 )
XMVECTOR XM_CALLCONV XMVector3TransformCoord(
	FXMVECTOR V,                    // 결과가 점이므로 벡터의 4번째 값이 자동으로 1로 설정됨
    CXMMATRIX M);                   // 입력 행렬
    
    
// 벡터와 행렬의 곱 함수 -> 결과 벡터 ( =  벡터 * 행렬,  != 행렬 * 벡터 )
XMVECTOR XM_CALLCONV XMVector3TransformNormal(
	FXMVECTOR V,                    // 결과가 벡터이므로 벡터의 4번째 값이 자동으로 0으로 설정됨
    CXMMATRIX M);                   // 입력 행렬

 

 


참고 : DirectX 12 를 이용한 3D 게임 프로그래밍 입문 / 한빛미디어

 

+ Recent posts