Fundamental Idea of Transformation
Numpy의 matrix multiplication을 이용하든 OpenGL transformation function을 이용하는 것이든,
결국 transformation의 기본적인 접근은 행렬의 곱을 이용하는 것이다.
Current Transformation Matrix
OpenGL은 "state machine"이다.
즉, 하나의 상태가 지정되면 그 상태는 새로운 상태가 지정될 때까지 그대로 있는다.
상태는 current color, current transformation matrix 등이 포함된다.
OpenGL은 항상 current transformation matrix을 이용하여 object를 그린다.
Current transformation matrix가 C면,
우리가 <pre>glVertex3fv(p)</pre>을 해서 <pre>p</pre>을 그리더라도 실제로는 <pre>Cp</pre>가 그려진다.
각 렌더링을 시작할때는 반드시 <pre>glLoadIdentitiy()</pre>을 이용해서 current transformation matrix을 identity matrix로 설정해야한다.
Current transformation matrix가 identity라면, 모든 object들은 NDC(Nomalized Device Coordinate) space 위에 그려진다.
Transformation Functions
OpenGL은 manipulate the current transformation matrix을 지원하는 많은 함수를 가지고 있다.
- <pre>glScale*()</pre>
- <pre>glRotate*()</pre>
- <pre>glTranslate*()</pre>
- <pre>glMultmatrix*()</pre>
- <pre>glShear*()</pre>나 <pre>glReflect*()</pre>는 존재하지 않는다.
- 대신 shear나 reflect는 <pre>glMultMatrix*()</pre>을 이용해서 수행할 수 있다.
Current transformation matrix의 상태는 right-multiplication으로 변한다.
C ← CS가 되는 셈이다. 때문에 코드에서는 나중에 추가되는 요소가 실제로는 먼저 수행된다.
코드를 작성할 때에는 이를 잘 생각해야 한다.
glScale*()
어떠한 축의 방향으로 확대시킨다.
형태 : <pre>glSclae*(x, y, z)</pre>
- x, y, z : 각각 x, y, z 축에 대한 scale factor이다.
왼쪽 그림은 (0, 0), (0, 0.5), (0.5, 0)의 삼각형을 나타낸 것이다.
이 도형에서 <pre>glScalef(2.0, 1.0, 1.0)</pre>을 하면 오른쪽 그림과 같이 된다.
glRotate*()
어떠한 축을 중심으로 회전한다.
형태 : <pre>glRotate*(angle, x, y, z)</pre>
- angle : 회전시킬 각도이다. radian이 아닌 degree이다.
- x, y, z : x, y, z coordinate, 회전 축이 될 vector
(0, 0), (0, 0.5), (0.5, 0)의 삼각형에서 <pre>glRotatef(30, 0.0, 0.0, 1.0)</pre>을 수행하면 오른쪽 그림과 같이 된다.
xy평면을 보고 회전을 시키는 것이므로 z축이 중심이 되어야 한다. 또한 angle이 양의 값을 가지므로 반시계 방향이 된다.
glTranslate*()
평행 이동을 수행한다.
형태 : <pre>glTranslate*(x, y, z)</pre>
- x, y, z : x, y, z coord. Translation vector
(0, 0), (0, 0.5), (0.5, 0)의 삼각형에서 <pre>glTranslatef(-0.2, 0.0, 0.0)</pre>을 수행하면 오른쪽 그림과 같이 된다.
x축 방향으로 -0.2 만큼 평행이동 시킨 것이다.
glMultMatrix*()
현재의 current transformation matrix에 인자로 넘겨주는 matrix을 곱하여 그것을 transformation matrix로 삼는다.
형태 : <pre>glMultMatrixf(m)</pre>
- m : 4x4 column-major matrix
numpy의 ndarray는 row-major order로 데이터가 저장이된다.
때문에 ndarray을 이용해서 glMultMatrix에 적용하기 위해서는 transpose을 해야한다.
(0, 0), (0, 0.5), (0.5, 0)의 삼각형에서 다음과 같은 코드를 적용함으로써 translate을 수행할 수 있다.
아래에서 T는 x축으로 0.4만큼 움직이는 4x4 matrix이다. 이를 <pre>.T</pre>을 이용해서 transpose을 한 후 <pre>glMultMatrixf</pre>에 적용하였다.
T = np.identity(4)
T[:3, 3] = [0.4, 0.0, 0.0]
glMultMatrixf(T.T)
Composing Transformations
OpenGL의 transformation function은 right-multiplication으로 적용된다.
따라서 코드상으로는 맨 마지막 줄의 transformation이 실제로는 가장 먼저 적용이 된다.
따라서 아래와 같은 코드에서는 TRp가 되어 그려진다.
Right multiplication이므로, rotate → translate의 순으로 일어난다.
참고
본 포스트는 한양대학교 이윤상 교수님의 수업을 정리한 내용입니다.
출처: 한양대학교 이윤상 교수님 컴퓨터그래픽스 강의 강의자료 - https://cgrhyu.github.io/courses/2022-spring-cg.html
'Computer Science > Computer Graphics' 카테고리의 다른 글
Rendering Pipeline, Transformation Pipeline (0) | 2021.04.07 |
---|---|
Affine Frame (0) | 2021.03.23 |
Transformation in 3D (0) | 2021.03.16 |
Transformation in 2D (0) | 2021.03.16 |
[GLFW] Input handling (0) | 2021.03.13 |
댓글