4장 기하학적 객체와 변환 – 변환 학습목표 예제 - 회전입방체 표준 변환을 배운다 동차좌표 변환행렬의 유도 회전(rotation) 이동(translation) 크기변환(scaling) 밀림(shear) 동차좌표 변환행렬의 유도 간단한 변환으로부터 임의의 변환행렬을 구축하는 방법을 배움
입방체의 모델링 typedef GLfloat point3[3]; point3 vertices[8] ={{-1.0,-1.0,1.0},{-1.0,1.0,1.0}, {1.0,1.0,1.0}, {1.0,-1.0,1.0}, {-1.0,-1.0,-1.0},{-1.0,1.0,-1.0}, {1.0,1.0,-1.0}, {1.0,-1.0,-1.0}}; glBegin(GL_POLYGON); glVertex3fv(vertices[0]); glVertex3fv(vertices[3]); glVertex3fv(vertices[2]); glVertex3fv(vertices[1]); glEnd(); 다른 다섯 면도 같은 방법으로 정의할 수 있다
외향면의 정의 정점이 정의되는 순서를 반시계 방향으로 하면 보이는 면이 외향면이다 – 오른손법칙을 따름
객체의 표현을 위한 자료구조 6번의 glBegin(GL_POLYGON) 호출 24개의 정점들이 명시된 glBegin(GL_QUAD) 호출 위의 두 방법으로 입방체가 그려질 수 있지만 육면체의 위상적 특징을 나타내지 못한다
색입방체 GLfloat vertices[8][3]={{-1.0,-1.0,1.0},{-1.0,1.0,1.0}, {1.0,1.0,1.0}, {1.0,-1.0,1.0}, {-1.0,-1.0,-1.0},{-1.0,1.0,-1.0}, {1.0,1.0,-1.0}, {1.0,-1.0,-1.0}}; GLfloat colors[8][3]={{0.0,0.0,0.0},{1.0,0.0,0.0}, {1.0,1.0,0.0},{0.0,1.0,0.0}, {0.0,0.0,1.0},{1.0,0.0,1.0}, {1.0,1.0,1.0},{0.0,1.0,1.0}};
색입방체 void quad(int a, int b, int c, int d) { glBegin(GL_POLYGON); glColor3fv(colors[a]); glVertex3fv(vertices[a]); glColor3fv(colors[b]); glVertex3fv(vertices[b]); glColor3fv(colors[c]); glVertex3fv(vertices[c]); glColor3fv(colors[d]); glVertex3fv(vertices[d]); glEnd(); }
색입방체 5 6 2 4 7 1 3 올바른 외향 법선을 얻도록 정점의 순서가 주어졌음을 유의하라 void colorcube() { quad(0, 3, 2, 1); quad(2, 3, 7, 6); quad(0, 4, 7, 3); quad(1, 2, 6, 5); quad(4, 5, 6, 7); quad(0, 1, 5, 4); } 5 6 2 4 7 1 3 올바른 외향 법선을 얻도록 정점의 순서가 주어졌음을 유의하라
면에서 정점 색의 보간 쌍일차 보간
면에서 정점 색의 보간 삼각형의 쌍일차 보간
앞의 방법의 약점은 응용프로그램에서 모델을 구축하고 입방체를 그리기 위해서 많은 함수호출을 해야 한다는 점이다. 효율성 앞의 방법의 약점은 응용프로그램에서 모델을 구축하고 입방체를 그리기 위해서 많은 함수호출을 해야 한다는 점이다. 면으로 입방체를 그리는 것은 다음과 같은 함수호출을 요구 6 glBegin, 6 glEnd 6 glColor 24 glVertex 텍스처와 조명을 사용하면 더 늘어남
OpenGL은 정점배열(vertex array)이라고 하는 기능을 제공함으로써 배열 데이터를 저장할 수 있도록 한다 정점 배열 OpenGL은 정점배열(vertex array)이라고 하는 기능을 제공함으로써 배열 데이터를 저장할 수 있도록 한다 여섯 가지 종류의 배열이 지원된다 정점(vertex) 컬러(color) 컬러 인덱스(color index) 법선(normal) 텍스처 좌표(texture coordinates) 에지 플래그(edge flag) 우리는 정점과 컬러 배열만을 필요로 한다
컬러와 정점 배열을 사용하기 위해서 다음과 같이 인에이블한다 초기화 컬러와 정점 배열을 사용하기 위해서 다음과 같이 인에이블한다 glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); 배열의 위치를 지정 glVertexPointer(3, GL_FLOAT, 0, vertices); glColorPointer(3, GL_FLOAT, 0, colors); 3차원 배열 float로 저장 데이터배열 연속적 데이터
연속되는 네 개의 인덱스들이 입방체의 한 면을 기술 인덱스들과 면들의 사상 면 인덱스들의 배열을 구성 GLubyte cubeIndices[24] = {0,3,2,1, 2,3,7,6, 0,4,7,3, 1,2,6,5, 4,5,6,7, 0,1,5,4}; 연속되는 네 개의 인덱스들이 입방체의 한 면을 기술 디스플레이 답신에서 모든 glVertex 와 glColor 호출들을 대신하는 glDrawElements 를 이용해서 그린다
입방체 그리기 방법 1: 방법 2: 무엇을 그리는지 인덱스의 수 인덱스데이터의 형식 인덱스데이터의 시작 for(i=0; i<6; i++) glDrawElements(GL_POLYGON, 4, GL_UNSIGNED_BYTE, &cubeIndices[4*i]); 인덱스데이터의 형식 인덱스데이터의 시작 glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices); 하나의 함수로 입방체를 그림
일반적인 변환 변환은 점들을 다른 점들로 사상한다 (벡터를 다른 벡터로 사상) v=R(u) Q=T(P)
아핀변환 q = f (p) q = f (p1 + p2) = f(p1) + f(p2) 정점들의 선형조합 변환된 정점들의 선형조합
아핀변환 q = f (p) q = A p v = f (u) v = A u P’ = M P M is a 4x4 matrix, with 12 degrees of freedom v’ = M v M is a 4x4 matrix, with 9 degrees of freedom.
그래픽스에서의 중요성은 선분의 양 끝점만을 변환하고 구현으로 하여금 변환된 두 점을 연결하여 선분을 그리게 하면 된다는 점이다 아핀 변환 직선 보존 물리적으로 중요한 많은 변환들의 특성 강체변환: 회전, 이동 크기변환, 밀림 그래픽스에서의 중요성은 선분의 양 끝점만을 변환하고 구현으로 하여금 변환된 두 점을 연결하여 선분을 그리게 하면 된다는 점이다
파이프라인 구현 변환 래스터기 u v T T(u) T(v) 정점들 화소들 프레임 버퍼 (응용프로그램으로부터)
표기 P,Q, R: 아핀 공간에서의 점 u, v, w : 아핀 공간에서의 벡터 a, b, g : 스칼라 p, q, r : 점의 표현 -동차 좌표계에서의 4 스칼라 배열 u, v, w : 벡터의 표현
이동 새로운 위치로 점을 이동 벡터 d에 의해서 정해지는 변위 3 자유도 P’=P+d P P’ d
얼마나 많은 방법이 있는가? 하나의 점을 새로운 점으로 이동하는 방법은 무한히 많이 있을 수 있지만 많은 점들을 이동하는 방법은 보통 한 방법만 있을 수 있다 객체 평행이동: 모든 점이 같은 벡터만큼 이동
p’=[x’ y’ z’ 1]T d=[dx dy dz 0]T y’=y+dy z’=z+dz 표현을 사용한 이동 어떤 프레임에서의 동차좌표 표현을 사용하면 p=[ x y z 1]T p’=[x’ y’ z’ 1]T d=[dx dy dz 0]T 따라서 p’ = p + d , 즉 x’=x+dx y’=y+dy z’=z+dz 이 표현은 4차원이고 점 = 벡터+ 점 을 나타내고 있다
이동행렬 동차 좌표계에서 4 x 4 행렬 T 를 사용해서 이동을 나타낼 수 있다 p’=Tp 여기서 T = T(dx, dy, dz) = 모든 아핀 변환이 이 형식으로 표현될 수 있고 여러 개의 변환이 연결될 수 있으므로, 구현을 위해서 좋은 표현이다
회전 (2D) 원점을 중심으로 한 q 도의 회전 x = r cos (f + q) y = r sin (f + q) x’=x cos q –y sin q y’ = x sin q + y cos q x = r cos f y = r sin f
3차원에서 z 축을 중심으로 한 회전은 모든 점들에서 z 값들이 바꾸지 않는다 동차좌표계에서 p’=Rz(q)p x’= x cos q –y sin q y’= x sin q + y cos q z’ =z
회전 행렬 R = Rz(q) =
x 축과 y 축을 중심으로 한 회전 z 축을 중심으로 한 회전에서와 마찬가지로 R = Rx(q) = R = Ry(q) = x 축을 중심으로 한 회전에서, x 는 바뀌지 않는다 y 축을 중심으로 한 회전에서, y 는 바뀌지 않는다 R = Rx(q) = R = Ry(q) =
크기변환 각 축 방향으로 확장 또는 축소 (고정점은 원점) x’=sxx y’=syx z’=szx p’=Sp S = S(sx, sy, sz) =
반사 음의 크기변환 계수에 해당 sx = -1 sy = 1 original sx = -1 sy = -1 sx = 1 sy = -1
일반적 공식으로 역행렬을 구할 수 있지만 단순한 기하학적 사실을 이용할 수 있다 역 변환 일반적 공식으로 역행렬을 구할 수 있지만 단순한 기하학적 사실을 이용할 수 있다 이동: T-1(dx, dy, dz) = T(-dx, -dy, -dz) 회전: R -1(q) = R(-q) 임의의 회전행렬에 적용됨 cos(-q) = cos(q), sin(-q)=-sin(q) 이므로 R -1(q) = R T(q) 크기변환: S-1(sx, sy, sz) = S(1/sx, 1/sy, 1/sz)
밀림(shear) 하나의 기본 변환을 추가하는 것이 유익 면들을 반대방향으로 끄는 것과 마찬가지
밀림 행렬 x 방향으로의 단순한 밀림 x’ = x + y cot q y’ = y z’ = z H(q) =
연결 회전, 이동, 크기변환 행렬들을 곱함으로써 임의의 아핀변환 행렬을 구성할 수 있다 동일한 변환이 많은 정점들에 적용되므로 행렬 M=ABCD 를 구하는 비용은 많은 정점들 p 에 대해서 Mp를 계산하는 것에 비해서 무시할 만하다 응용에서 주어진 명세로부터 어떻게 원하는 변환행렬을 구성할 것인지가 어려운 부분이다
변환의 순서 오른쪽의 행렬이 처음으로 적용됨을 유의 수학적으로 다음은 등가적이다 p’ = ABCp = A(B(Cp)) 많은 문헌에서 점을 표현하기 위해서 행행렬을 사용. 행행렬로 나타내면, p’T = pTCTBTAT
R(q) = Rz(qz) Ry(qy) Rx(qx) 원점을 중심으로 한 일반적 회전 원점을 중심으로하는 회전은 x, y, z 축을 중심으로 한 회전들의 연결로 분해될 수 있다 R(q) = Rz(qz) Ry(qy) Rx(qx) qx qy qz Euler 각이라고 한다 회전들의 순서는 교환적이지 않음을 주의 다른 순서로 회전할 수 있지만 각도가 달라진다
원점을 중심으로 한 일반적 회전
원점이 아닌 고정점을 중심으로 한 회전 고정점을 원점으로 이동 회전 고정점을 원래의 위치로 이동 M = T(pf) R(q) T(-pf)
모델링에서, 흔히 원점에 축 방향으로 있고 표준적인 크기인 단순한 객체로부터 시작한다 사례화(instancing) 모델링에서, 흔히 원점에 축 방향으로 있고 표준적인 크기인 단순한 객체로부터 시작한다 정점들에 사례변환(instance transformation)을 적용 크기변환 방향지정 위치지정
사례화(instancing)
임의의 축에 대한 3D 회전 1. Po 를 원점으로 옮김 2. u 를 z-축과 일치시킴 3. z-축 중심으로 만큼 회전 4. 2번 역순 5. 1번 역순
임의의 축에 대한 3D 회전 u를 정규화 v 가 x-z 평면에 닿을 때까지 x축을 중심으로 회전 v 가 z 축에 닿을 때까지 y축을 중심으로 회전
임의의 축에 대한 3D 회전 일련의 회전들
임의의 축에 대한 3D 회전 x 와 y 의 계산 방향 코사인들
임의의 축에 대한 3D 회전 x 회전의 계산
임의의 축에 대한 3D 회전 y 회전의 계산
임의의 축에 대한 3D 회전