inverse matrix와 포인터 입력
이번에는 역행렬입니다.
이름만 들으면 살짝 무섭지만, 역할은 단순합니다. 변환을 되돌리는 것입니다.
사용자의 포인터는 screen 좌표로 들어옵니다. 그런데 회전된 사각형 안을 클릭했는지 확인하려면 local 좌표에서 검사하는 편이 훨씬 쉽습니다. 그러려면 screen에서 local로 되돌아가야 합니다. 이때 inverse matrix가 등장합니다.
왜 local로 되돌릴까
회전된 사각형을 화면 좌표에서 직접 hit test하려면 계산이 복잡합니다. 그런데 포인터를 사각형의 local 좌표로 되돌리면 질문이 쉬워집니다.
0 <= localX <= width
0 <= localY <= height
이렇게 끝입니다. 사각형이 화면에서 아무리 돌아가 있어도 local 안에서는 여전히 반듯한 사각형입니다. 어려운 세상을 쉬운 좌표계로 끌고 오는 겁니다.
역행렬은 변환을 되돌린다
최종 변환이 screenMatrix * worldMatrix라면, 포인터를 local로 되돌릴 때는 그 역행렬을 곱합니다.
localPoint = inverse(screenMatrix * worldMatrix) * pointer
2D matrix에서 determinant는 역행렬이 존재하는지 판단하는 데 중요합니다.
det = a*d - b*c
M^-1 exists when det != 0
scale이 0에 가까워지면 determinant도 작아지고 역변환이 불안정해집니다. 그래서 에디터에서는 최소 scale을 제한하는 경우가 많습니다. 오브젝트를 0배로 줄이면 수학도 “저는 이제 모르겠습니다” 하고 물러납니다.
빠른 검사와 정확한 검사
모든 오브젝트에 대해 매번 정확한 inverse hit test를 하면 비용이 커질 수 있습니다. 그래서 보통 두 단계로 나눕니다.
1. AABB broad phase로 후보를 줄인다.
2. 후보에만 inverse local hit test를 수행한다.
AABB는 빠르지만 거칠고, inverse test는 정확하지만 더 비쌉니다. 둘을 같이 쓰면 편집기가 훨씬 차분해집니다.
데모에서 볼 것
데모에서는 회전된 박스를 클릭하며 screen point가 local point로 되돌아가는 값을 확인합니다.
오늘의 핵심은 이것입니다. hit testing을 어렵게 만들지 말고, 포인터를 쉬운 좌표계로 데려오세요. 역행렬은 그 되돌아가는 길을 만들어주는 도구입니다.