3 분 소요

3차원 공간에서의 회전

Image

  • 2차원 공간에서의 회전은 1 자유도(DOF)
    (시계 <-> 반시계 회전이며, 서로 반대됨)

  • 3차원 공간에서 회전은 3 자유도
    YawPitchRoll
    이런식으로 3차원 공간에서의 물체의 회전 상태를 표현하는 것을
    ‘오일러 각도’ 라 표현한다

오일러 각도(Euler Angles)

Image

각각의 ‘축’에 대한 회전 행렬을
‘곱’하여 회전 행렬을 만든다
(그렇기에 곱하는 순서가 정해져 있어
축에 종속적이기도 하다)

(이건 Column Major 이기에 오른쪽에서 왼쪽으로 적용됨
Z -> Y -> X 순으로 회전 적용)
(Roll -> Yaw -> Pitch)

  • 또한 ‘축’ 자체가 다른 회전에 영향을 받음

Image

이미 기울어진 Pitch에 대하여 다시 Roll의 회전까지 적용하기도 함

자이로스코프를 통해 보면 이해가 비교적 쉬운편
바깥의 원의 이동에 안쪽의 원이 영향을 받음

그렇기에 아래와 같은 짐벌락 현상이 발생할 수 있음

Image

왼쪽의 원에서 초록색 원이 90도 회전하며
파란색 원과 합쳐진 상태이며

이후, 파란색 원과 초록색 원을 ‘분리할 수 없는’ 현상이 발생
(두 축이 겹쳐버린 현상)

Image

수식으로 보자면
결과적으로 2개의 각도만이 회전 결과에 반영됨을 볼 수 있다
(마지막 줄)

  • UpVector와 ViewVector(현재 정면 관찰)가 각각 존재할때
    RightVector는 Cross로 구할 수 있다

  • 그런데 ViewVector를 회전시켜 하늘을 바라보게 하였을때
    UpVector와 동일해지므로
    이 때는 Cross를 통해 RightVector를 정의할 수 없음
    (다소 극단적인 예시이긴 하다)

그렇기에 오일러 벡터 외에도 회전을 표현할만한 방식이 필요해짐

  • 그래도 오일러 벡터는 ‘직관적’이며 이해하기 쉽다는 장점이 있어
    에디터, Tool, UI 등으로 회전을 표현하는 방식으로
    여전히 사용된다

  • 또한 ‘입력’에 대한 수치로도 사용됨
    (Right 로 90도 회전 등)

쿼터니언 (Quaternion, 사원수)의 개념

Image

3차원 공간의 회전을 위하여 1가지 숫자를 추가한
4개의 숫자로 회전을 표현하는 방식
(숫자가 4개이기에 4원수)

  • 숫자가 4개라도 3자유도
    (마지막 숫자인 w에 대한 제약 조건이 존재하기에)

  • 회전 행렬과 호환
    회전을 쿼터니언으로 진행 후, 회전 행렬로 변환할 수 있음
  • 회전의 보간(Interpolation)에 유리함

쿼터니언의 사용 방식

Image

벡터 V를 회전축 N에 대하여 T만큼 회전시키고 싶을때

    1. 쿼터니언 p = (v,0)
    1. 쿼터니언 q = (n sin(t/2),cos(t/2))
    1. 켤레 쿼터니언 q* = (-n sin(t/2),cos(t/2))
    1. 쿼터니언 p’ = (v’,0) = qpq* 로 회전
  • 켤레?
    어떤 수에서 ‘특정 성분’의 부호를 바꿔 ‘짝’을 이루는 수
    (ex : a + bi -> a - bi)

-> 직접 구하기 보단 이미 구현된 라이브러리를 사용하는 편

Image

또는 쿼터니언 q로부터 회전 행렬을 만들어 곱함
회전 행렬을 쿼터니언으로 만들어서 사용할 수도 있음

(메모리를 아끼기 위해 행렬이 아닌 쿼터니언으로 저장하는 방식도 존재)

쿼터니언의 구성

Image

4개의 숫자 x,y,z,w 로 이루어짐
(x,y,z 를 u로 표현하여 (u,v)로 표현하기도 함)

여기서 i,j,k는 허수
(허수는 제곱하여 -1 이 되는 실제로는 없는 수)

  • i^2 = ijk = -1
  • ij = k = -ji
  • jk = i = -kj
  • ki = j = -ik

그래서 이런 허수와 회전이 무슨 관계?

Image

허수는 곱할때마다
i -> -1 -> -i -> 1 로 순환하는 특성을 가짐

실수와 허수의 좌표를 가지는 좌표계에서
하나의 ‘회전’으로 볼 수 있음

Image

특정한 좌표 p가
실수 부분 2, 허수 부분 i 정도의 값을 가진다면
p를 p = 2 + i 로 표현이 가능
(이런식으로 허수 + 실수의 표현을 ‘복소수’ 라고 함) 이때, i를 곱하게 되면
그래프에서 90도 정도 회전하게 된
q와 동일해짐!
(q = 2i - 1)

  • i를 계속 곱하면 같은 원리로 p -> q -> r -> s -> p가 됨
    허수를 곱해줌으로서 ‘복소수’가 회전하는 듯한 효과를 얻을 수 있음

Image

그렇기에 쿼터니언은
3개의 허수를 이용하여 회전을 표현한다

각각의 허수 좌표 및 연산을 통하여
쿼터니언 만의 독자적인 회전 표현이 가능해짐

  • i에 j를 곱하면 k, j에서 i를 곱하면 -k 등

쿼터니언의 기본연산 방식

Image

  • 4개의 수가 모두 같으면 같은 쿼터니언 판정

  • 덧셈, 뺄셈은 각각의 요소에서 진행

Image

식이 많아보이지만 기본적으로는 항을 정렬하게 되면
가장 아래쪽의 식으로 변환된다
(다항식의 전개)
(‘복소수’의 곱셈만 주의하면 충분히 전개할 수 있는 식)

  • dot과 Cross를 사용하여 더 깔끔한 요약이 가능

Image

쿼터니언의 절댓값은
4개의 요소를 제곱한후 더하고, 루트를 씌우면 된다

Image

쿼터니언의 역수를 구하는 방식

먼저 켤레(Conjugate)를 구하고
(q = (u,w)라면 q* = (-u,w))

이후

qq* = q ^ 2 = q* ^ 2 이므로
q^-1 = q* / ( q ^2) 로 정의
   

|q| = 1 이라면
q^-1 = q*

  • 역수?
    곱했을때 1로 만드는 수
    (일반적인 숫자는 1 / a 등으로 역수를 만들 수 있다)

쿼터니언의 회전

Image

앞에서 본 것의 식을 푸는 과정

  • 이러한 식을 외우기 보다는 ‘쿼터니언’의 개념을 이해하고
    일반적인 오일러 각도와 차이점이 있다는 점을 느낀다면 일단 충분!
    (엔진 등을 구현하려면 이러한 부분을 구현해야 할지도?)
    (Math 라이브러리 등으로 엔진의 일부분을 대체하는건가?)

댓글남기기