좌표/벡터를 다른 좌표/벡터로 매핑
1차 함수(Linear Functions)로 제한
평행 이동도 포함되어야 하기에 호모지니어스 좌표 표현 도입
물리 시뮬레이션의 기초
직선을 유지하는 성질
변환 전에 선분이라면 변환 후에도 선분
선분 전체의 모든 점을 변환할 필요가 없음
선분은 두 꼭짓점을 이은 것, 선분의 꼭짓점만 변환
변환한 꼭짓점을 다시 연결하면 선분 전체가 변환된 것과 동일함
Rigid Body (강체)
형태가 고정된 물체
회전/평행이동 가능
Non-Rigid Body
물체의 크기/모양에 변화 가능
스케일링/기울임
물체의 크기를 확대하거나 축소하는 연산
모든 점들에 동일한 scaling matrix 적용

물체를 기울이는 연산
2D Horizontal Shear
주어진 x좌표에 y좌표와 비례하는 값을 더하면, 원점에서 멀어질 수록 x축 방향으로 기울어짐

2D Vertical Shear
y축 방향으로 기울어짐

원점을 기준으로 좌표를 회전하는 연산
CCW(반시계방향)으로 회전
시계방향으로 θ만큼 회전 시, 반시계방향으로 -θ만큼 회전 (= 2π-θ)

주어진 좌표를 벡터만큼 이동
행렬로 표현하기 위해 호모지니어스 좌표 도입

2D 어파인 변환 = 3D 행렬(3x3) 연산
회전 후 평행이동 연산의 행렬식
여러 연산을 미리 계산하여 합성하면 순서대로 연산한 것과 같은 결과가 나옴

변환 행렬은 매핑 과정이라 곱셈 순서에 따라 다른 결과가 나옴
회전 후 평행이동과 평행이동 후 회전은 전혀 다른 연산 결과가 나타남

2D 회전은 원점 중심으로 회전해버림
Pivot: 회전 중심이 되는 고정점
원형 궤도를 도는 우주선을 그리는 프로그램
우주선의 방향은 바뀌어야 함

#version 330 core
in vec4 aPos; // vertex position: attribute
in vec4 aColor; // vertex color: attribute
out vec4 vColor; // varying color: varying
uniform mat4 uMat; // matrix: uniform
void main(void) {
gl_Position = uMat * aPos; // transformation
gl_Position.z *= -1.0F; // negation
vColor = aColor;
}
glm::vec4 vertPos[] = { // small triangle
{ 0.0F, 0.1F, 0.0F, 1.0F }, // v0
{ -0.1F, -0.1F, 0.0F, 1.0F }, // v1
{ 0.1F, -0.1F, 0.0F, 1.0F }, // v2
};
glm::vec4 vertColor[] = { // all red
{ 1.0F, 0.3F, 0.3F, 1.0F, },
{ 1.0F, 0.3F, 0.3F, 1.0F, },
{ 1.0F, 0.3F, 0.3F, 1.0F, },
};
// 단위행렬
GLfloat mat[16] = {
1.0F, 0.0F, 0.0F, 0.0F,
0.0F, 1.0F, 0.0F, 0.0F,
0.0F, 0.0F, 1.0F, 0.0F,
0.0F, 0.0F, 0.0F, 1.0F,
};
const float radius = 0.6F;
float theta = 0.0F;
system_clock::time_point lastTime = system_clock::now();
void updateFunc(void) {
// update the rotation angle
system_clock::time_point curTime = system_clock::now();
milliseconds elapsedTimeMSEC = duration_cast<milliseconds>(curTime - lastTime); // in millisecond
theta = (elapsedTimeMSEC.count() / 1000.0F) * (float)M_PI; // 2초당 1회전
// calculate the matrix
mat[0] = cosf(theta); mat[4] = -sinf(theta);
mat[1] = sinf(theta); mat[5] = cosf(theta);
mat[12] = radius * cosf(theta);
mat[13] = radius * sinf(theta);
}
void drawFunc(void) {
...
GLuint locMat = glGetUniformLocation(prog, "uMat");
glUniformMatrix4fv(locMat, 1, GL_FALSE, mat); // false면 열 우선방식으로 저장
glDrawArrays(GL_TRIANGLES, 0, 3);
...
}
원 궤도를 그리며 움직이는 삼각형이 출력
