etc

각도 표현방식 Quaternion - Euler 변환(python 코드)

J-Mook 2021. 9. 16. 22:37
반응형

3차원 좌표계에서 회전각을 표현하는 방식 중, 대표적으로 쿼터니언(Quaternion) 방식과 오일러(Euler)방식이 있다.

Euler

이 방식은 보다 직관적인 방식으로, 임의 방향의 회전을 x, y, z 성분으로 나누어 Roll, Pitch, Yaw라는 이름으로 표현하는 방식이다.
이 간단한 방식으로 3차원에서 모든 방향에 대한 회전을 표현할 수 있다.

Gimbal Lock

하지만 위의 Euler 방식에는 큰 단점이 존재하는데, Gimbal Lock이 발생할 수 있다는 것이다.
Gimbal Lock 이란 두개 이상의 회전축이 일치되는 현상으로, 다음 그림과 같은 상황이다.

 

위와 같은 현상이 문제가 되는 이유는, Gimbal Lock이 발생할 경우 그만큼 자유도를 잃기 때문이다. 만약 모든 축에 대해 Gimbal Lock이 발생한다면, 물체는 한개의 축방향으로 밖에 회전할 수 없다.

Computational Efficiency


추가적인 Euler방식의 단점으로는 x축 각도, y축 각도, z축 각도 각각 회전변환을 계산해야하므로, 3x3 행렬의 회전변환 필요하게된다.
이는 비교적 연산량이 많아지는 결과를 만든다.

Quaternion

이 방식을 사용하는 위에서 서술한 Euler방식에서 발생하는 문제들을 모두 해결할 수 있다.

이 방식은 각 축에 대한 회전을 표현하는 것이 아닌, 한개의 축에 대해서만 회전을 표현하므로, 이를 시각화하면 다음 그림과같이 표현된다.

이 방식은 한가지 축만을 사용하므로, 두개 이상의 축이 곂쳐 발생하는 Gimbal Lock 현상이 발생하지 않고, 회전을 표현하는데 회전축 벡터(x,y,z), 회전 각(w) 만을 사용하므로, 연산효율 면에서도 Euler 방식보다 효율적이다.
하지만 직관적이지 않다는 단점이 있다.

오일러 - 쿼터니언 변환 코드(python)

def euler_from_quaternion(x, y, z, w):
    t0 = +2.0 * (w * x + y * z)
    t1 = +1.0 - 2.0 * (x * x + y * y)
    roll_x = math.atan2(t0, t1)

    t2 = +2.0 * (w * y - z * x)
    t2 = +1.0 if t2 > +1.0 else t2
    t2 = -1.0 if t2 < -1.0 else t2
    pitch_y = math.asin(t2)

    t3 = +2.0 * (w * z + x * y)
    t4 = +1.0 - 2.0 * (y * y + z * z)
    yaw_z = math.atan2(t3, t4)

    return roll_x, pitch_y, yaw_z # in radians

(단, 벡터 (x, y, z)는 단위벡터 이다.)

필요하다면 복붙해서 사용하자.

반응형