그래픽스

Quaternion

춤추는수달 2022. 1. 4. 22:35

필요성 : 기존의 오일러 회전 방식의 문제점 짐벌락 현상 때문. 여러 회전축의 회전이 결합되면 생기는 문제이다. 설명하자면 어떤 축이 회전함에 따라 다른 축이 변화하게 되는데, 이 때문에 두 축의 방향이 겹치는 순간 하나의 축이 소실되어버리는 현상이 나타난다. 세 개의 축을 회전시킬 때 두 번쨰로 회전시키는 축이 이 문제를 일으킨다. 

 

사원수 : 사원수는 놀랍게도 복소수를 이용해 회전을 한다. 두 복소수를 곱하면 복소수를 극좌표계로 표현했을 때 각도를 더한 벡터가 나온다. 

 

삼차원 벡터 회전 공식 : 벡터 V를 a 축으로 Th 만큼 회전시킨 벡터 V' = v*cosTh + (v . a)*a*(1-cosTh) + (a x v)sinTh

 

쿼터니언 q는 xi + yj +zk + w의 형태 또는 Vect(x,y,z,w) 또는 허수부 벡터 v와 실수부 s를 합친 (v, s)로 표현된다. 이 때 i, j, k는 i와 같은 허수로서 다음의 성질을 가진다.

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

q의 성질

q * q^-1 = 1, q의 길이 = 루트( x^2 + y^2 + z^2 + w^2)

q1(v1, s1)과 q2(v2, s2)의 곱셈  q1q2 = (v1 x v2 + s1v2 + s2v1, s1s2 - v1v2)

a x b x c = b(a . c) - c(a . b)

 

어떤 벡터 V(v, 0)를 쿼터니언 q(u, w)를 이용해 회전변환 하기

V' = qVq^-1

=(u, w)(v, 0)(-u,w)

= (u,w)(-v x u + wv, v . u)

= ((w^2 - u . u) + 2(u . v)u + 2w(u x v) , 0)

= ((c^2 - s^2)v + 2s^2(n . v). n + 2.c.s(n x v), 0)  // #( w = c, u = s . n)

= cos(2Th)v + (1-cos(2TH))(n . v) . n + sin(2Th) . (n x v)

 -> 회전 공식의 형태와 같다.

 

어떤 쿼터니언 q(x,y,z,w)를 행렬로 바꾸면 

M(q) = 1 - 2y^2 - 2z^2 , 2(xy - wz) , 2(xz + wy)

          2(xy + wz) , 1 - 2x^2 - 2z^2 , 2(yz - wz)

          2(xz - wy) , 2(yz + 2x) , 1- 2x^2 -2y^2

가 된다. 

그 반대로 행렬 M을 쿼터니언 q(x,y,z,w)로 바꾸면

 w = 1/2(Root(M00 + M11 + M22 + 1)), x = (M21 - m12) / 4w , y = (M02 - M20) / 4w , z = (M10 - M01) /4w 

이다.

사실 위에선 w를 먼저 계산하고 나머지 x,y,z를 w를 이용해 계산했다. 그런데 정수 나눗셈에선 오차가 발생할 수 있기 때문에 w먼저 하지 않고 다른 것먼저 계산해도 된다.

'그래픽스' 카테고리의 다른 글

CPU 파이프라인  (0) 2022.01.27
Lighting  (0) 2022.01.02
Index Buffer  (0) 2021.12.08
Constant Buffer  (0) 2021.11.10
장치 초기화  (0) 2021.10.13