월세 500 호기심 천국
4주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (2/2) 본문
4주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (2/2)
원펀치 쓰리 갓냥이 2024. 1. 18. 04:390주차: 인트로 - 새롭고 신기한 것을 좋아하거나, 모르는 것을 알고 싶어 하는 마음
1주차: Unity 엔진은 왜 개발 언어로 C#을 선택했을까?
2주차: 의외로 세상 잡다한 Transform에 대한 모든 것
3주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (1/2)
4주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (2/2)
5주차: 헐크 아저씨도 깜짝 놀란 Unity Render Pipeline이 작동하는 과정
6주차: 매 프레임 나보다 갓생 사는 Unity의 Life Cycle
7주차: 남들보다 더 갓생 사는 Coroutine의 충격적인 정체
8주차: 야물(YAML)딱진 그 녀석의 은밀한 속마음 - Unity Scene 파일 (.unity)
9주차: 내 과자 포장지 누가 버렸어? - meta data 파일 (.meta) 파헤치기
10주차: 철가방 채로 배달온 Unity 빌드 파일. 난 단무지 시킨 적 없는데, 왜 있지?
11주차: 마무리 - 후기
사실 물체의 회전을 표현하는 방식에 오일러 각만 존재하는 것은 아니다.

기존의 3개의 실수로 구성되어있던 오일러 각과 달리
1개의 실수, 3개의 허수 부분으로 구성된 사원수(Quaternion)라는
새로운 수 체계로 3차원 회전을 표현할 수 있다.
복소수: a + bi
사원수: a + bi + cj + dk
실수만으로는 전부 나타낼 수 없는 부분을 허수의 힘을 빌려 나타낸다는 점에서
복소수와 사원수가 다소 비슷해 보일 수 있으나,
몇 가지 공통점과 차이점이 있다.
공통점은 위 수식에서도 볼 수 있듯이 새로운 허수 단위를 사용한다는 것이다.
복소수의 경우 i, 사원수의 경우 i, j, k를 활용하며,
두 경우의 허수들 모두 제곱할 경우 -1이 된다는 특징이 있다.
복소수: i² = -1
사원수: i² = j² = k² = -1
위 식만을 볼 경우
i, j, k의 제곱값이 같다면, 그럼 결국 모두 다 같은 값인 것 아닌가?
할 수 있겠지만, 사원수의 경우 다음 한 가지 규칙이 추가된다.
ijk = -1
때문에 만일 i = j = k을 만족할 경우 i³ = -1이 성립됨으로 인해
i² = j² = k² = -1의 공식이 깨져버리기 때문에
i, j, k는 모두 다른 허수 값임을 알 수 있다.
쉽게 이해하자면 다음과 같다.




xy 좌표계에서 x와 y가 아예 다른 단위인 것처럼,
i, j, k 역시 서로 아예 다른 단위인 것이다.
어째서 시작부터 i, j, k가 서로 다른 단위임을 이토록 강조하는 것일까?
아예 다르다라는 것은 독립적이라는 의미고,
그것은 곧 서로에 대해서 종속적이지 않다는 것이기 때문이다.


4차원 좌표로 회전을 표현? 어떻게?
3차원 물체의 회전을 4차원 좌표로 표현한다는 것은 조금 낯설어보일 수도 있겠다.
하지만 이는 이미 기존의 2차원 좌표계에서도 이미 잘 쓰이고 있었다.

위 복소수 평면에 원을 그리고,
원 위에서 임의의 점 P를 회전시킨다고 해보자.
점 P가 초기에 R축 위 1 지점에 있다고 할 때,
점을 반시계 방향으로 90도 회전시키고 싶다면 P의 좌표에 i를 곱하면 된다.
점 P에 i를 곱해 90도 회전시키면
1에서 i로, i에서 -1로, -1에서 -i로, 그리고 다시 1로 돌아오는 것을 확인할 수 있다.
이처럼 회전을 복소수 좌표계로 나타내면
물체의 회전을 곱셈으로 나타낼 수 있다는 큰 메리트가 생기게 된다.
회전을 곱셈으로 나타내는게 왜 메리트?
2주차에서 다뤘던 것처럼 Transform에서 위치 이동, 크기 조정, 좌표계 변환 등의 작업을 할 때
기존 행렬에 변환행렬을 곱해주는 작업을 하기 때문이다.
회전 작업을 곱셈으로 나타낼 수 있다면
물체 회전 역시 변환행렬 곱셈 작업의 반열에 오르게 되어 작업의 능률이 상승할 것이고,
실제로도 그렇게 되고 있다.
위의 복소수 평면에서의 경우
회전축은 평면에서 수직으로 뚫려 나오는 방향으로 1개, 좌표 단위는 I, R로 2개였다.
그렇다면 회전축이 3개 필요한 3차원 회전의 경우 몇 개의 좌표 단위가 필요할까?
삼원수를 활용해 3개의 단위만으로 표현해보려는 시도도 있었지만,
결론부터 말하자면 4개이다.
3개의 회전축을 필요로 했던 오일러 각이 3개의 단위를 사용하고
하나의 회전축이 잠겨버렸던 것에서 짐작할 수 있었듯이,
회전축이 1개인 복소수 평면에서는 필요한 단위가 2개였던 것처럼,
우리가 직접 통제 가능한 단위의 개수는 회전축의 수보다 최소 1개 이상은 더 많아야 했다.
그리고 마침 1개의 실수 부분과 3개의 허수 부분, 총 4개의 단위를 사용하는 사원수는 이 조건을 충족했다.
이제 3차원 물체의 회전에 사원수(Quaternion)을 적용하기 위한 준비는 끝났다.



쿼터니온느는 새로운 모델의 불판을 제안했다.
기존의 x y z에 더불어 w라는 새로운 단위를 탑재한,
언젠간 자신이 재학 중인 4차원 좌표계 공학과의 졸업 작품으로 만들어보고자 구상했던,
자신의 이름을 딴 쿼터니언 불판이었다.
보일러가 만들었던 기존의 불판은 x y z 순서대로 세 번의 회전을 거쳐
마지막 최종 회전의 모습을 보여줬다면,
쿼터니언 불판은 x y z에 원하는 회전축의 벡터의 정보를 담고,
w에 회전각 정보를 넣어 그만큼 회전시켰다.
단 한 번의 회전으로 모든 작업이 끝났기 때문에
회전 순서에 따라 결과가 달라질 일도 없었고,
회전축의 방향이 제한되어있지 않고
회전축 벡터를 원하는 대로 지정할 수 있었기 때문에
이전과 달리 공간상으로 최단거리를 따라 이동하게끔 회전을 유도할 수 있었다.
때문에 이전처럼 회전 과정에서 보간의 오류를 야기하지도 않았다.
회전축이 잠길 일도 없었기 때문에 짐벌락 현상 역시 찾아볼 수 없었다.

쿼터니언 회전의 한계
제한된 180˚ 이상의 회전
물론 장점만 있는 것은 아니었다.
쿼터니언 불판은 180˚이상의 회전을 한 번에 나타낼 수 없었다.
위에서 말했듯 공간상으로 최단거리를 따라 이동하게끔 되어있었기 때문에,
사전에 180 + α만큼 회전하도록 의도하고 설계했다면,
실제로 실행시켜보면 더 짧은 거리인 180 - α만큼 반대 방향으로 회전하는 것이었다.
물론 이는 보간 과정에서의 모호성을 없애기 위해서는 감당해야 할 수 밖에 없는 현상으로,
만약 180˚ 이상의 회전을 표현하고 싶은 경우
한 번의 회전이 아닌 두 번 이상의 회전으로 나누어 표현하거나,
반드시 거쳐야 하는 중간 지점을 설정해두면 해결될 일이었다.
직관적이지 못한 표기법
보일러가 만든 불판과 비교되는 가장 큰 단점이라면 단점인 부분이었다.
오일러 각으로 나타낸 (45, 0, 60), (30, 90, 0) 등의 회전각들을 보면
짐벌락이 발생하지 않는 선에서는
직관적으로 회전 이후의 모습을 예상하기 쉬웠다.
세 개의 축과 세 번의 회전이라는 오일러 각의 작동 원리가
우리 머릿속에서도 재현되기 쉬울 정도로 쉽고 직관적이었기 때문이다.
반면 쿼터니언 회전의 (10, 50, 30, 60)를 보고
회전이 적용된 이후의 고기 모습을 쉽게 예상할 수 있는 학생은 없었다.
고기가 원하는 각도까지 도달할 수 있도록 하려면 얼마만큼 회전시켜야 하는지
쿼터니언으로 나타낼 수 있는 학생도 얼마 되지 않았다.
이렇듯 더 좋은 결과의 회전을 만들어낼 수 있고 연산 횟수가 적어 컴퓨터와 불판에게는 친근했어도,
정작 불판을 만지는 학생들에게는 그렇게 쉽게 가까이 다가갈 수는 없는 표현 방식이였다.

그럼에도...
그럼에도 보일러와 쿼터니온느는 힘을 합쳐 새로운 모델의 불판을 제작해내기로 했다.
다만 둘은 어느 한 명의 의견만을 반영해 단점을 그대로 안고 가지 않고,
둘 모두의 방법을 응용, 서로의 단점을 보완해 최고의 불판이 나오도록 협업했다.

학생들이 직접 불판의 조종값을 입력하고 현재의 회전값을 확인하는 데에는
직관성이 뛰어난 보일러의 불판(Euler Angle)을 응용했다.
반면 목표한 회전값까지 기계가 계산해서 자동으로 회전시켜 주는 데에는
회전축과 각도의 제약이 없어 회전이 자유로운 쿼터니온느의 불판(Quaternion)을 응용했다.
3차원 좌표계 공학과 학생과 4차원 좌표계 공학과 학생의
이런 민족 대통합과도 같은 훈훈한 일화는 세대를 타고 전해져 내려와
현대로도 이어져 Unity 시스템에도 그대로 담겨 차용되고 있다.
Unity 인스펙터 창의 Transform → Rotation란의 Vector3 회전값은 오일러 각을 사용한다.
C# 스크립트 상에서 물체의 현재 회전값을 확인하고 싶을 때도 Transform.eulerAngle에 접근해 알아낸다.
하지만 우리가 물체를 직접 회전시키거나 회전값을 수정하고 싶을 때에는 Quaternion.Euler(x, y, z)를 사용한다.
(x, y, z)에 우리가 원하는 물체의 오일러 각을 넣으면,
컴퓨터가 그것에 대응되는 알맞은 쿼터니언으로 변환하고 회전에 사용한다는 것이다.

이렇게 싸울듯 말듯 투닥투닥 다투던 보일러와 쿼터니온느는
어느 순간 자신들의 감정이 깊어져 가는 것을 확인했고
대학을 졸업한 후 결혼에 성공적으로 골인했다.
끝.

뭐요.
0주차: 인트로 - 새롭고 신기한 것을 좋아하거나, 모르는 것을 알고 싶어 하는 마음
1주차: Unity 엔진은 왜 개발 언어로 C#을 선택했을까?
2주차: 의외로 세상 잡다한 Transform에 대한 모든 것
3주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (1/2)
4주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (2/2)
5주차: 헐크 아저씨도 깜짝 놀란 Unity Render Pipeline이 작동하는 과정
6주차: 매 프레임 나보다 갓생 사는 Unity의 Life Cycle
7주차: 남들보다 더 갓생 사는 Coroutine의 충격적인 정체
8주차: 야물(YAML)딱진 그 녀석의 은밀한 속마음 - Unity Scene 파일 (.unity)
9주차: 내 과자 포장지 누가 버렸어? - meta data 파일 (.meta) 파헤치기
10주차: 철가방 채로 배달온 Unity 빌드 파일. 난 단무지 시킨 적 없는데, 왜 있지?
11주차: 마무리 - 후기
'내 맘대로 쓰는 Unity 심층분석 析深層分' 카테고리의 다른 글
| 6주차: 매 프레임 나보다 갓생 사는 Unity의 Life Cycle (1) | 2024.02.04 |
|---|---|
| 5주차: 헐크 아저씨도 깜짝 놀란 Unity Render Pipeline이 작동하는 과정 (3) | 2024.01.27 |
| 3주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (1/2) (1) | 2024.01.13 |
| 2주차: 의외로 세상 잡다한 Transform에 대한 모든 것 (1) | 2024.01.07 |
| 1주차: Unity 엔진은 왜 개발 언어로 C#을 선택했을까? (2) | 2023.12.29 |