Notice
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

월세 500 호기심 천국

3주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (1/2) 본문

내 맘대로 쓰는 Unity 심층분석 析深層分

3주차: EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (1/2)

원펀치 쓰리 갓냥이 2024. 1. 13. 19:50
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주차: 마무리 - 후기

 


 

아주 먼 옛날, 세상에 스마트폰과 챗GPT가 보급되지 않았던 시절,

마법이라는 이름으로 수학과 과학이라는 신비로운 학문을 연구하던 시대가 있었다.

 

그리고 여기, 영국의 명문 제빵 마법 학교호그로와상에 두 에이스 학생,

보일러 드리프트쿼터니온느 그라인더가 있다.

 

보일러는 불속성 마법 융합대학 소속의 3차원 좌표계 공학과 학생이었고,

쿼터니온느는 같은 융합대학 소속의 과만 다른 4차원 좌표계 공학과 학생으로 둘은 친하게 지내는 편이었다.

 

그러던 어느 날, 호그로와상 불속성 마법 융합대학의 MT가 열렸다.

MT에 참석한 학생들은 각 학과들끼리 모여 바비큐 파티를 가지려 했으나,

얇고 넓은 사이즈의 바비큐 고기에 비해

좁고 강한 세기의 숯불로 학생들의 파티는 난항을 겪었다.

고기를 골고루 굽고 싶었으나 고기의 중심부만 가열되는 것이었다.

 

이에 3차원 좌표계 공학과의 에이스 보일러 학생은 다음과 같은 방식으로 고기를 굽기 시작했다.

 

 

보일러의 동기들은 이 현란한 불판의 움직임을 보며

바비큐 고기의 모든 부분을 골고루 구울 수 있는 최고의 방식이라고 극찬했다.

 

그러나 이 방식을 옆 테이블에 지켜본

4차원 좌표계 공학과의 에이스 쿼터니온느는 화들짝 놀랐다.

 

 

아니 저런 식으로 구우면, 불판을 원하는 대로 회전시킬 수 없을 텐데?

과연 고기를 제대로 구울 수나 있을까?

 

똑똑한 쿼터니온느가 우려했던 위 불판에서의 문제점은,

바로 3차원 회전에서 발생할 수 있는 짐벌락 현상이었다.

 

이에 3차원 좌표계 공학과 학생들과 4차원 좌표계 공학과 학생들은

위 문제에 관련된 심도 깊은 토론을 하기 위해

즉시 모든 바비큐 파티를 중단하고 테이블을 한데 모아 긴급 회의를 시작했다.

 


오일러 각

오일러 각은 3차원 공간에 놓인 물체의 회전 상태를 세 번의 축회전으로 나타내는 각도 표현 방식이다.

예를 들어 오일러 각이 (45, 60, 20)인 물체는

X축 회전으로 45도, Y축 회전으로 60도, Z축 회전으로 20도 회전한 결과물이라고 볼 수 있다.

 

이 회전 방식의 독특한 점은

물체가 회전할 시, 자신을 제외한 다른 회전축들 역시 같이 회전할 수 있다는 것이다.

예를 들어 X축 회전 시 Y, Z축이,

Y축 회전 시 Z축이 같이 회전할 가능성이 생긴다.

 

이러한 회전축들 사이의 독립적이지 않은 종속적인 관계가,

이어서 나오게 될 오일러 각의 여러 한계들을 유발하는 결정적 원인이 된다.

 


오일러 각의 한계

1. 회전 순서에 따라 달라지는 결과

하나의 회전축자신을 제외한 다른 축들에게도 영향을 주는 묘한 특성 때문에,

물체를 회전시키는 순서에 따라 아예 다른 결과물이 나오게 된다.

아주 같은 케이스는 아니지만 비슷한 케이스를 조금 보도록 하자.

 

학생 A와 B는 학교 운동장에서 보물지도를 발견했다.

보물지도에는 다음 세 문장이 적혀있었다.

 

1. 이곳에서 오른쪽을 보고 삼 보 이동하시오.
2. 그곳에서 왼쪽을 보고 이 보 이동하시오.
3. 그곳에서 오른쪽을 보고 삼 보 이동하시오.

 

같은 보물지도를 발견한 학생 A와 B였지만, 기억한 내용은 달랐다.

학생 A는 지도에 적힌 순서대로(1→2→3) 길을 맞게 찾아갔고,

학생 B는 거리와 방향은 정확히 기억했지만 순서를 헷갈려(1→3→2) 도착한 곳이 달라지게 되었다.

 

A 학생( 1→2→3 )과 B 학생(1→3→2)의 이동 경로 차이

A와 B 모두 1, 2, 3 문장을 합쳐

총합 오른쪽으로 여섯 보, 왼쪽으로 이 보 이동한 것은 똑같은데,

어째서 도착한 곳이 달라진 걸까?

 

이는 이동하기 위해 서 있던 곳에서 오른쪽/왼쪽을 바라보는 행위가,

그 다음 순서의 오른쪽/왼쪽의 기준을 바꾸었기 때문이다.

 

오일러 각에서의 회전 역시 마찬가지다.

축끼리의 회전이 독립적이지 못하고 종속적이기 때문에,

X축의 회전은 다음 회전에 쓰일 Y, Z축의 형태에 영향을 끼치고,

다음 회전의 모양이 달라지게 된다.

당연하게도 Y, Z축의 회전 역시 마찬가지이다.

 

위에서 언급한 (45, 60, 20) 오일러각의 경우도

X를 45도 회전, Y를 60도 회전, Z를 20도 회전하는 경우와

X를 45도 회전, Z를 20도 회전, Y를 60도 회전하는 경우의 회전 결과가 다르게 나타나는 것이다.

 

때문에 실제로 오일러각을 나타내는 방법에는 다음 12가지가 있다.

XYZ, ZXY, ZXZ, XYX, YXY, YZY,

ZYZ, ZXZ, XZY, YXZ, YZX, ZYX

 

(α, β, γ)의 각도가 주어지고 위 12가지 방법에 따라

XYZ의 경우 X를 α만큼, Y를 β만큼, Z를 γ만큼,

ZXY의 경우 Z를 α만큼, X를 β만큼, Y를 γ만큼

순서에 따른 차이를 발생시키지 않기 위해

미리 약속된 순서대로 주어진 각도를 회전시키는 방식이다.

 

이렇게 어떻게든 해결책이 마련이 되기는 했지만,

회전 순서에 따라 결과가 달라질 수 있다는 점은

여전히 회전을 표현하는 방식에 있어서 크나큰 단점이다.

 

어후 3차원 애들이란 ㅉㅉ

 

2. 보간의 문제

학술적인 연구도 중요하지만 결국 배고픔 앞에 장사가 없다는 것을 알아차린 호그로와상 불속성 마법 융합대학 학생들은,

결국 회의를 중단하고 다시 바비큐 파티를 재개했다.

회의를 통해 별 다른 대안을 찾지 못했기 때문에 학생들은 보일러의 불판을 계속 사용했고,

 

이는 쿼터니온느의 심술을 돋구기에 충분했다.

쿼터니온느에게 있어서 배고픔보다도 더 거부감이 드는 것은

3차원 좌표계 공학과 학생들의 멍청함과 안일함이기 때문이었다.

군침을 흘리며 기다리는 학생들을 보다못한 쿼터니온느는 결국 불판을 담당하는 보일러에게 요청했다.

고기 아랫부분이 조금 덜 익은 것 같아서,
불판을 (-90, 90, -90) 오일러 각으로 회전시켜줘.

 

쿼터니온느의 속셈을 몰랐던 보일러는 그대로 불판을 회전시켜 주었다.

그리고 고기가 익기를 조금 기다린 뒤,

쿼터니온느는 우매한 3차원 좌표계 공학과 학생들에게 결정적인 한 방을 날렸다.

고기 아랫부분이 이제 적당히 익은 것 같아.
이번엔 불판을 다시 (0, 0, 0) 오일러 각으로 회전시켜줘.

 

보일러는 쿼터니온느의 요청대로 불판을 회전시켜 주었다.

그리고 이윽고 보여지는 광경에,

3차원 좌표계 공학과 학생들은 충격과 공포에 빠져 그대로 그 자리에 얼어붙어버렸다.

 

 

 

수직 위 방향(-90, 90, -90)을 가리키고 있던 고기는

직관적인 일직선 궤적이 아닌

알 수 없는 이상한 궤적을 그리며 원위치(0, 0, 0)로 돌아오는 것이었다.

 

끼야아아아악

 

 

이 현상의 원인을 이해하기 위해 알고 있어야 하는 오일러 각의 또 하나의 특징은

(α, β, γ) 각에서 α, β, γ은 모두 -180°와 180° 사이의 각을 가진다는 것이다. (or -π ~ π)

여기서 -180°와 180°는 같은 크기의 각이고,

180°에서 1°를 더한 181°의 경우 -179°와 완전히 같다.

 

각도는 결국 회전이고,

한 바퀴를 회전하든 두 바퀴를 회전하든

회전한 바퀴수가 각도에 표현되어야 할 이유는 없기 때문에

360°를 주기로 -180°과 180° 사이를 반복하게 되는 것이다.

 

여기서 문제가 생긴다.

아까와 마찬가지로 보물지도 문제이다.

학생 A와 B는 학교 운동장에서 보물지도를 찾았다.

보물지도에는 다음 세 문장이 적혀있었다.

 

1. 운동장의 중심을 기준으로 반지름 10m의 원을 그리고,
2. 가장 북쪽인 지점을 0°로 하라.
3. 이때 -120°와 60°, 원 위에서 두 지점 사이의 정확한 중간 지점을 찾아라.

 

같은 보물지도를 발견했지만, 학생 A와 B의 해석은 달랐다.

학생 A는 단순히 (-120 + 60) / 2 = -30임을 인식해 -30° 지점으로 달려가 열심히 땅을 파기 시작했다.

반면 학생 B는 -120° = 240°임을 이용, (240 + 60) / 2 = 150임을 인식해 150° 지점으로 달려가 열심히 땅을 파기 시작했다.

 

A: (-120 + 60) / 2 = -30     ------------------------------------------------------------     B: (240 + 60) / 2 = 150

 

결국 두 지점 모두 나름의 정답이었고,

이러한 중간값의 모호성은 컴퓨터로 하여금 우리가 의도하지 않은 계산값을 내놓게 한다.

 

컴퓨터를 이용해 게임 혹은 영화의 애니메이션을 제작할 때,

우리는 위치와 각도의 보간값을 많이 사용한다.

보간값은 임의의 두 지점 사이의 중간값, 혹은 사전에 정해둔 비율의 사잇값으로,

대상의 더 매끄러운 움직임을 구현하기 사용된다.

 

예시를 들자면 주인공이 검을 휘두르는 모션을 제작하기 위해

검을 위로 치켜드는 프레임에서 팔의 각도를 0°,

검을 아래로 내리친 이후의 프레임에서 팔의 각도를 90°로 설정하고

그 사이의 프레임을 0°와 90°사이의 수없이 많은 보간값들로 채워

검을 든 팔이 부드럽게 내려가는 모습을 연출하는 것이다.

 

하지만 이 계산을 컴퓨터에게 맡기게 된다면 문제가 발생할 수 있다. 

개발자는 0° 10° → 45° → 80° → 90°의 각도 변화를 의도했겠지만,

컴퓨터는 0° → -10° → -135° → 100°(-260°) → 90°(-270°)로 팔이 반대방향으로 돌 수도 있는 것이다.

오일러 각에서 45°와 -135° 모두 0°와 90°의 중간값이기 때문.

 

 

까 보일러가 고기 굽던 불판을 다시 생각해보자.

위 불판이 이상한 궤적을 그리며 원위치로 돌아온 이유는 계산이 잘못돼서가 아니라,

(-90, 90, -90)에서 (0, 0, 0)으로 이동할 때

공간상으로 가까운 지름길 좌표들을 거치는 것이 아닌,

 

오일러 각으로 나타내었을 때 수치적으로 정직하게 가까운 좌표인

(-90, 90, -90) (-45, 45, -45) (0, 0, 0)

를 거쳐 이동했기 때문이다.

 

10°와 363° 중 1°에 더 가까운 것은 무엇일까?

수치상으로 보았을 때는 10°이다. 1°에서 9°만큼만 더 이동하면 되기 때문이다.

하지만 실제 공간상으로 나타내어 보았을 때는 1°에서 무려 362°나 더 가야 하는 363° 더 가까운 곳에 있다.

 

또한 우리가 직접 보고 생각하는 1°와 363°의 중간값과 ((1 + 3) / 2 = 2°)

컴퓨터가 생각하는 1°와 363°의 중간값은 다르다. ((1 + 363) / 2 = 182 = -178°)

 

이러한 모호성, 그리고 각도의 수치상의 크기공간상에서의 크기와 일치하지 않는 특성은

회전 계산에 있어서 오일러 각의 크나큰 맹점이다.

 

그니까 고기 그만 구워라 보일러

 

3. 짐벌락

바비큐 장에 잠시 혼란이 찾아왔지만, 학생들은 이내

'회전 과정에서 약간의 궤도 이탈이 일어나는 것 정도는 고기가 구워지는데 문제가 되지 않는다.'

라고 판단, 불판을 계속해서 보일러에게 맡기고 고기를 굽기 시작했다.

 

쿼터니온느는 이 상황이 정말로 마음에 들지 않았다.

그녀 내면의 심술 뚜껑이 날아가 버릴 정도로 속이 매우 매우 끓고 있었다.

보일러가 모두에게 주목받는 것도, 바비큐 파티의 영웅이 되는 것도,

모두 그저 끔찍한 상황이라고 생각했다.

 

쿼터니온느는 보일러에게 다시 은근슬쩍 다가가 요청했다.

 

아까 고기를 밑부분 밖에 안 구웠었잖아.
윗부분도 야무지게 구워지게 (90, 0, 0)로 불판을 회전시켜줘.

 

보일러는 쿼터니온느의 행동을 이해하지 못했다.

분명 어제까지만 해도 친한 친구였는데,

어째서 갑자기 나를 계속해서 함정에 빠트리고 난처하게 만드는 거지?

내가 무엇을 잘못한 거지?

 

하지만 보일러는 학생들에게 맛있는 고기를 먹이고 싶었다.

(90, 0, 0)로 불판을 회전시키면 실제로 고기의 윗부분이 밑으로 내려가게 되기 때문에,

쿼터니온느의 말에 일리가 있다 생각하고 불판을 회전시켰다.

 

고기의 윗부분이 맛있게 구워지는 동안,

쿼터니온느는 다음 말을 내뱉어버렸다.

 

불판이 고장난 거 아냐? 이래서는 Y각을 바꿔도, Z각을 바꿔도 결과가 같아지는데?
회전축이 하나는 어디 가고 왜 두 개밖에 안남은 거야?

 

 

 

이제 제발 그만...

 

이 일에 충격을 받은 보일러는 그야말로 펑펑 울었다.

세상이 자신을 억까한다는 생각이 들었고

계속해서 자신을 괴롭히는 쿼터니온느가 원망스러워졌다.

 

고기의 모든 면을 자유자재로 구워야 할 수 있는 불판이,

3차원 회전임에도 불구하고 회전축이 3개에서 2개로 줄어드는 일

자기 자신이 보기에도 도저히 용납할 수 없었다.

 

보일러는 세상이 미웠다.

보일러와 쿼터니온느 사이의 신경전을 그저 웃기다며 구경만 하고 있는 학생들도 미웠다.

 

보일러는 몽둥이를 들고와 자신이 만들었던 불판을 마구 부수기로 마음 먹었다.

불판이라면 고기의 모든 면을 잘 구워내야 하는 것을,

제대로 회전도 못하면 그걸 어따 쓰농!

이라면서.

 

보일러가 몽둥이를 들어올리려는 찰나,

쿼터니온느가 그 앞을 가로막아섰다.

보일러가 들고있는 몽둥이를 뺏어 저 멀리 던졌고,

찌질하게 그만 좀 울으라고 휴지를 앞에 툭 내놨다.

 

보일러는 그런 쿼터니온느의 행동을 도무지 이해할 수 없었다.

얜 대체 왜 이러는 걸까.

 

모두의 주목 속에서 보일러의 울음이 그치려는 찰나,

쿼터니온느가 그 원리를 차분히 설명했다.

 

짐벌락은 아까 보간의 문제 부분에서 보았던 고기 불판의 기이한 움직임에서 추가로 이어진다.

불판이 (-90, 90, -90)에서 (0, 0, 0)로 바로 회전할 수 없었던 이유는

보간의 문제를 이용해서도 설명할 수 있지만,

 

다음 예시에서와 같이 컴퓨터 모델로 직접 구현하여 실행해보면

불판이 잘 회전을 하다가 어느 순간

불판을 회전시켜 줄 수 있는 회전축이 하나가 사라진다는 것을 알 수 있다.

 

가장 바깥쪽 회전과 가장 안쪽 회전이 '아예 같은 회전'이 되어버렸다

 

서로 다른 회전축에 수직인 두 개의 평면이 아예 포개어지는 상황이 발생하고,

물체의 현재 상태를 기준으로 X, Y, Z축 방향 모든 곳으로 회전할 수 있었던 불판이,

어느 순간 하나의 회전 방향잃게 된 것이다.

 

이런 식으로 특정 조건에서 하나의 회전축 자유도를 잃게 되는 현상짐벌락이라고 하며,

이는 3차원 공간의 회전에서 오일러 각이 제대로 쓰일 수 없는 가장 큰 이유가 된다.

 


 

세 가지 회전축을 사용하는 오일러 각은

회전 순서에 따라 결과값이 달라지는 모순이 있으며,

두 각도 사이의 보간값이 항상 정확하지는 않다는 모호성이 있고,

심지어 특정 조건을 만족시킬 경우 하나의 회전축이 아예 사라지는 문제가 있다.

 

그렇다면 3차원 공간에서 물체의 회전을 온전히 표현할 수 있는 방법은 아예 없는 것일까?

만약 있다면, 대체 어떤 방법을 사용해야 할까?

 

그저 학생들과 함께 골고루 익힌 고기가 먹고 싶어

직접 기지를 발휘해 불판을 만들고 맛있게 고기를 구워보려 하는 보일러를,

굳이 못 굽게 막고 딴지 걸고 지독하게 괴롭히는 쿼터니온느는,

대체 무슨 꿍꿍이인걸까?

 

이는 다음 주,

EulerAngle아, Quaternion아, 둘이 싸우지 말고 사이좋게 지내야 한다~ (2/2)

에서 이어서 다루어보겠다.

생각지도 못하게 양이 많아져 2부작이 되었다...

 

 

 


 

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주차: 마무리 - 후기