물리 시뮬레이션 엔진을 만들어 볼까 하고 책을 봤는데 고등학교 수학과 물리 수준이다. 그래서 약간 더 보충하여 정리 해 본다. 컴퓨터 게임 엔진은 3가지 정도의 일을 한다. 화면에 그림을 그리고 소리를 내는 표현 작업, 게임 세계 속의 물리 현상을 시뮬레이션 하는 작업, 게임 세계 속의 인공 지능을 처리하는 작업이다. 화면에 그림을 그리는 작업은 보통 1/30초 주기로 반복한다. 매우 빨리 그린다. 물리 현상은 좀 더 섬세하게 작업하기 위해서 1/30초의 간격을 3등 분하여 1/90초 주기로 반복하는 것이다. 시간을 섬세하게 나누면 좀 더 정밀한 시뮬레이션이 가능하다. 게임 캐릭터가 있을 때 이 놈은 물리 엔진, 인공 지능 엔진, 게이머의 명령 이렇게 3가지를 받게 된다. 예를 들어 어디로 가라는 명령은 사용자가 내린다. 그런데 그 곳으로 가는 경로는 인공 지능이 판단하여 만든다. 그 곳으로 가는 도중에 절벽에서 떨어지거나 어떤 물체와 충돌할 때 물리 현상은 물리 엔진이 담당한다. 3가지 명령이 중첩되어 혼란스럽지 않도록 명확하게 구분해야 한다.
먼저 화면 좌표를 이해야 한다. 고등학교 수학 시간에 배운 좌표계와 컴퓨터 화면의 좌표계가 다르다. 수학에선 y축과 z축은 하늘 방향을 향한다. 3D에선 x, y가 땅의 평면이고 z가 하늘 방향이다. 컴퓨터에선 x, y방향은 글을 쓰는 방향, 책을 읽는 방향과 관계가 있다. 모니터 화면에서 x방향은 글을 쓰거나 읽는 방향이고, y는 행이 늘어나는 방향이다. 3D에서 z는 원근의 깊이를 나타낸다. 그리고 컴퓨터 그래픽 라이브러리에 따라서 좌표계가 다르기 때문에 수학 좌표계와는 다르다는 것만 알고 있으면 된다.
2D 점 : (x ,y)
3D 점 : (x ,y, z)
2D 선 : (x1, y1) – (x2, y2)
3D 선 : (x1, y1, z1) – (x2, y2, z2)
2D 면 : (x1, y1) – (x2, y2) – (x3, y3)
3D 면 : (x1, y1, z1) – (x2, y2, z2) – (x3, y3, z3)
2D 선 : (x1, y1) – (dx, dy), dx=x2–x1, dy=y2–y1
3D 선 : (x1, y1, z1) – (dx, dy, dz), dx=x2–x1, dy=y2–y1, dz=z2–z1
2D 중심점(평균공식) : ((x1+x2)/2, (y1+y2)/2)
3D 중심점(평균공식) : ((x1+x2)/2, (y1+y2)/2, (z1+z2)/2)
2D 선의 방정식 : Ax + By = C
3D 면의 방정식 : Ax + By + Cz = D
2D 원의 방정식 : x*x + y*y = r*r
3D 구의 방정식 : x*x + y*y + z*z = r*r
점, 선, 면을 어떻게 표현할까? 고등학교 때 본 바와 같이 점을 2개 묶어서 선을 나타내고, 점을 3개 묶어서 삼각형 면을 나타낸다. 또는 선을 2개 묶어서 면을 나타낸다. 2개의 점으로 선을 나타내는 것보다는 한 점과 벡터(방향과 길이가 있는 화살표)로 선을 나타내는 것이 더 편하다. 이 직선을 연장해야 할 필요가 있을 때는 직선의 방정식을 사용하여 표현을 바꾼다. 책에선 직선의 방정식을 이용하면 충돌 검사에 좋다고 하는데 2D에서만 그렇다. 컴퓨터 속의 직선은 무한 길이의 직선이 아니다. 길이에 한계가 있는 어떤 물체의 경계선이기 때문에 수학적으로 직선의 교점을 구하는 문제와는 다르다. 예를 들어 2D에선 두 직선의 기울기가 다르면 당연히 교점이 생긴다. 기울기가 같고 절편도 같으면 두 직선은 완전히 일치한다. 그러나 직선의 길이에 제한이 있을 때는 그 교점이 두 직선의 중간에 있는지 추가 검사해야 한다. 두 직선의 교점을 구하는 문제는 가우스 소거법(선형결합법)과 치환법(x, y, z 중에 어느 하나의 값이 구해졌을 때)으로 구할 수 있다. 그런데 3D에선 직선의 식이 2D와 다르다. 2D의 직선의 방정식과 비슷한 것을 만들면 3D에선 면의 방정식이 된다. 비슷한 경우로 2D의 원의 방정식은 3D에선 구의 방정식이 된다. 선이 면으로 바뀌면서 입체가 된 것이다. 그렇다면 3차원에선 어떻게 직선을 표현하지? 3차원의 직선은 2차원 면인 x-y면, x-z면, y-z면 3개의 면에 투영된 직선의 방정식으로 표현이 된다. 두 직선이 기울기가 같다면 3개 면에 투영된 직선도 기울기가 같아야 한다. 3개 면에서 기울기와 절편이 일치하면 완전히 일치하는 직선이 된다. 만약 기울기가 일치하지 않으면 교점이 있을 수 있다. 만약 교점이 있다면 3개 면에 투영된 직선에서 구한 교점들이 서로 일치해야 한다. 교점이 발견 되었다면 직선의 길이 범위 안에 있는지 확인해야 한다. 그래서 연습 차원에서 2D 직선의 교점을 구하는 문제를 먼저 훑어 본다.
2D 직선 방정식 일반형 : Ax + By = C
2D 직선 방정식 특수형 : y = mx + d 또는 x = my + d
2D 직선의 기울기 공식 : m = dy/dx 또는 m = dx/dy
2D 직선의 직교 확인 : m1 x m2 = -1
그림에서 본 바와 같이 2D 직선 방정식 일반화 꼴에서 기울기를 구하는 특수한 꼴로 변형하여 계산하면 교점이 있는지 쉽게 확인이 가능하다. 문제는 일반형에서 특수 형으로 변형할 때 0으로 나누는 경우를 막아야 한다. 즉, 수직선, 수평선인지 먼저 확인을 해야 한다는 것이다. 수직선이나 수평선인 경우는 문제가 쉽게 풀린다. 이런 것을 특수한 경우라고 부른다. 보통 어떤 상수나 변수가 0이 되거나 1이 되는 경우에 이런 특수한 경우가 발생한다. 이 경우가 아니라면 간단하게 기울기를 구해서 비교해 보면 교점이 있는지 확인할 수 있고, 직교하는지도 쉽게 확인이 된다. 그런데 잘 생각해 보면 컴퓨터 속의 직선이란 A점에서 시작해서 B점에서 끝나는 길이가 한정된 직선이다. 어떤 물체의 경계선이기 때문이다. 고로 일반형의 직선의 방정식을 구하는 것이 더 어렵고 특수형의 직선의 방정식을 구하는 것이 더 쉽다. 특수형을 구해서 일반형을 구하는 것이 더 쉽게 되어 있다.
1단계 기울기 공식 : m = dy/dx = (y – y1) / (x – x1)
2단계 특수형 변환 : y = m(x – x1) + y1 = mx + (y1 – mx1) = mx + d
3단계 교점 구하기 : x = -(d1 – d2)/(m1 – m2)
4단계 교점 범위 확인 : 교점이 두 점의 사이에 있는지 확인
컴퓨터 속에선 직선의 길이가 유한하기 때문에 직선의 방정식 일반형을 사용할 일이 없을 것이다. 수직선인지 수평선인지 확인한 후에 기울기와 절편으로 표현되는 특수형을 사용할 일이 많다. 이렇게 하면 교점을 구하기도 쉽고, 두 직선이 수직인지도 확인하기 쉽다. 2D에서 교점 구하는 방법은 그대로 3D에서도 이용한다. 단지 3개 평면에 대해서 3회의 계산을 하고, 그 교점이 서로 일치하는지 확인해야 한다. 직선의 교점을 구하는 방법으로 사물의 충돌을 확인하기는 참 어렵다. 3D에서 상자 모양의 물체의 충돌을 상상해 보라. 검사할 것이 매우 많다. 그런데 사물을 원이나 공으로 보고 충돌 검사를 하면 매우 쉽다. 중심 좌표 사이의 거리를 구한 후에 서로 반지름의 합과 비교하면 3D에서도 아주 쉽게 충돌 검사를 할 수 있다. 여기에는 고등학교 때 배운 피타고라스 정리가 필요하다. 물론 원과 직선의 교점과 접점을 구하는 문제를 풀어 본 기억이 있을 것이다. 그러니까 직선과 원의 충돌 검사도 가능하다. 하지만 계산이 복잡하다. 3D 게임에선 상자, 원통, 공 모양 3개를 결합해서 충돌 검사를 한다. 직교 좌표계를 대변하는 상자(박스/큐브), 원통 좌표계를 대변하는 원통(실린더), 구좌표계를 대변하는 구(스피어)는 계산이 비교적 쉽기 때문이다. 2D에선 원과 사각형(마름모)으로 충돌 검사를 한다.
반지름 1인 원의 둘레 = 2π = 360도, 고로 1라디안 = 360/2π도
Y = sin(Θ), X = cos(Θ), tan = Y/X = sin/cos
반지름 1인 원의 공식 : sin*sin + cos*cos = 1
일반 형태 : y = Asin(fx + d), A=진폭, f=주파수, d=위상
고등학교 수학 시간에 배운 삼각 함수는 필수이다. 게임에서 3각 함수 사용하지 않는 곳은 거의 없다. 3각 함수 공식들 중에 꼭 외워야 하는 것들은 위와 같은 정도다. 나머지는 거의 게임에서 사용하지 않는다. 라디안과 각도 사이의 변환 공식은 잘 알고 있어야 한다. 대부분의 컴퓨터 언어의 함수에선 라디안을 사용한다. 하지만 우린 각도에 익숙하기 때문에 각도와 라디안 변환 공식을 사용한다. 이 변환 공식을 사용하면 계산 시간이 느려진다. 고로 라디안으로 생각하는 습관을 가지는 것이 좋다. 0도, 30도, 45도, 60도, 90도의 sin, cos, tan 값은 암기하고 있는 것이 좋다.
고등학교 때에 벡터나 행렬을 이유도 모르고 배웠을 것이다. 벡터를 사용하는 이유는 물리학 때문이다. 행렬은 좌표와 벡터 계산에 편리하기 때문에 사용한다. 벡터란 방향과 크기를 가진 표현 형태로 물리학에서 힘, 가속도, 속도 등을 표현할 때 사용한다. 에너지에서 힘이 나오고, 힘에서 가속도가 나오고, 가속도로 인해 속도가 변하고, 속도가 변해서 위치가 변한다. 에너지와 위치는 방향이 없는 스칼라 양이지만, 그 중간에 있는 것은 단순히 세기만으로는 표현에 문제가 있고 방향도 함께 표현을 해야 완벽하다. 물리 시뮬레이션을 할 때는 삼각함수와 벡터와 행렬이 필수적이기 때문에 다시 고등학교 수학의 기억을 회복해야 한다.
2D 위치 벡터 표기 : A = (x, y)
3D 위치 벡터 표기 : A = (x, y, z)
2D 방향 벡터 표기 : A = (dx, dy) @ (x, y)
3D 방향 벡터 표기 : A = (dx, dy, dz) @ (x, y, z)
위의 벡터 표기는 점의 위치를 표기하는 것과 별로 다를 것 없어 보인다. 이런 것을 위치 벡터라고 부른다. 위치 벡터란 것은 원점에서 그 좌표까지 가는 화살표를 말한다. 그냥 좌표 표기와 다를 것이 없기 때문에 무의미하고 실제로 컴퓨터에서 사용할 때는 어떤 위치에서 어느 방향이란 것이 의미가 있다. 위의 @ 표시는 영어의 at 대신 사용한 것이다. 그런데 이것도 보면 앞에서 본 직선의 표현과 다를 것이 없다. 여기까지 보면 벡터를 왜 사용하는지 모를 것이다. 단위 벡터란 화살표 길이가 1인 벡터이다. 이것은 앞에서 본 삼각함수와 유사하다. 반경이 1인 원에서 삼각함수를 계산한다. 고로 단위 벡터는 삼각함수와 호환이 된다. 즉, 2D에선 단위 벡터나 삼각함수나 다를 것이 없다. 2D에선 직각 좌표계와 극좌표계의 변환이 삼각함수를 이용하면 간단하다. 그럼 3D에선 어떻게 될까? 3D에선 최소 2개의 각도가 필요하다. 축을 기준으로 하든, 면을 기준으로 하든 2개의 각도가 있어야 구좌표계로 표현 가능하다. 앞에서 3D에서 일반적인 직선의 방정식을 만들기 어려운 것과 비슷하다.
벡터 연산 중에서 덧셈과 뺄셈은 많이 사용한다. 예를 들어 한 물체를 두 사람이 끈다고 했을 때 약간의 각도가 벌어져 있고, 서로 당기는 힘이 A와 B라면 물체는 어느 방향으로 어떤 힘으로 끌려 갈까? 그 방향과 힘을 C라고 표시할 수 있다. 위의 그림에서 첫 번째 그림과 같은 방법의 벡터 합이다. 속도를 변화시키는 가속도를 더하는 경우에도 해당이 된다. 두 번째 그림은 위치 벡터의 합인 경우다. 먼저 A만큼 가고, B만큼 가면 C에 도착한다는 그런 내용이다. 내용을 보면 알겠지만 더하는 순서는 상관 없고, 빼기 순서만 상관 있다. 그리고 더하기 계산법은 매우 간단하다. 각 X, Y, Z 성분을 합하고 빼기만 하면 된다. 고로 3D에서도 사용하기 쉽다.
벡터 곱에는 2가지가 있다. 내적과 외적이다. 베터 연산을 할 때는 벡터의 시작 점을 원점에 놓는다. 앞에서 3D에서 직선의 교점을 구하는 것이 2D에 비해서 매우 번거롭다는 것을 보았을 것이다. 2D에선 교점과 법선(수직인 직선)을 구하는 것이 쉬웠다. 기울기만 구하면 됐다. 3D에서도 법선(노멀 벡터)을 구하는 것이 쉽다. 벡터 외적을 하면 법선 벡터를 쉽게 구한다. 이것은 빛의 반사나 물체의 충돌에서 반사 방향을 결정할 때 기준이 된다. 물론 어떤 표면을 2개의 벡터로 나타내야 하는 조건이 붙는다. 즉, 3개의 점은 면을 정하고, 교차하는 2개의 직선은 면을 정한다는 것을 이용한 것이다. 계산 공식은 매우 외우기 쉽다. X성분을 구할 때는 Y와 Z성분만 이용한다. 잘 보면 규칙이 보일 것이다. 법선 벡터의 크기는 두 벡터가 이루는 평행사변형의 면적과 같다. 벡터 외적의 물리적인 의미는 법선 벡터를 구하는 것이라고 한다면, 내적의 의미는 무엇일까? 내적의 결과는 벡터가 아닌 스칼라 양이다. 즉, 크기만 있고 방향이 없다. 공식도 매우 간단하다. 같은 성분끼리 곱하기만 하면 된다. 내적은 벡터의 성분을 분해할 때 이용한다. 두 벡터가 서로 벌어지면 내적이 적고, 두 벡터가 서로 일치하면 내적은 두 벡터의 크기 곱이 된다. 벡터 내적을 사용할 때는 하나는 단위 벡터로 크기가 1이고 방향만 나타내는 것을 사용한다. 그러면 그 방향으로 분해된 벡터 성분을 구할 수 있다. 3D에서 힘을 어떤 방향 성분으로 분해할 때 사용한다.
행렬은 연립방정식을 풀 때도 도움이 되지만 벡터나 좌표 계산에도 도움이 된다. 연립방정식을 푼다는 얘기는 교점을 구한다는 것과 같은 것이다. 행렬 계산법을 잘 보면 앞에서 정한 벡터 연산과 유사한 면이 있다. 즉, 벡터의 합과 내적에 그대로 사용할 수 있다. 행렬의 곱과 합에 대해선 고등학교 수준의 기초적인 내용이라서 더 이상 언급할 필요가 없다. 전치 행렬이란 대각선을 기준으로 대칭이 되는 행렬이다. 예를 들어 벡터나 위치를 표시하기 위해서 행렬을 사용한다면 세로와 가로 형태 2가지가 가능하다. 이 두 가지 표현을 서로 바꿀 수 없는 상황이라면 전치 행렬이란 것을 구하면 된다. 예를 들어 좌표나 벡터가 세로 형인 계산법을 만들었다고 했을 때, 가로 형을 사용하는 시스템에서 계산하려면 계산에 들어가는 3x3 행렬을 대각선에 대칭으로 뒤집어야 한다. 행렬을 사용하는 본격적인 이유가 다음에 나온다.
3D에선 회전, 확대, 이동을 transform(변형)이라고 한다. 이 변형 표현을 행렬로 하면 깔끔하게 표현 된다. 물론 행렬로 표현했다고 해서 밑 바닥의 사칙 연산을 달리하는 것은 아니다. 미분적분도 결국은 4칙연산으로 실현된다. 회전, 확대, 이동 중에서 이동과 확대/축소 행렬은 매우 단순하다. 복잡한 것은 회전 행렬이다. 3D 공부하면 오일러 회전공식이나 사원수(4원수)란 말을 듣게 되는데, 이 중에서 오일러 회전 공식은 X, Y, Z 축의 회전을 중첩하여 임의의 회전을 얻는 것이다. 사람이 회전 결과를 이해하기 좋기 때문에 표현은 이렇게 하지만 실제로 컴퓨터 내부에선 사원수(허수의 확장판)로 변환해서 계산한다. 3D 게임 세계 속의 객체는 자신의 중심 좌표를 가지고 있다. 그래서 이동 부분과 회전과 확대 부분을 분리하여 계산할 수 있다. 회전과 확대는 객체의 중심 좌표에 대해서 수행하는 것이고, 객체의 위치는 세계 좌표에 대해서 수행하는 것이라서 분리 되어 있다. 모든 변형을 조합해서 하나의 변형 행렬로 만들 수는 있으나 이렇게 사용하지는 않는다. 5개의 변형 행렬을 따로 분리해 놓아야 처리하기 편하다. 회전 행렬의 유도 과정을 이해하고 싶다면 X, Y, Z축 중에서 어느 하나를 0으로 놓고 계산해 보면 쉽게 유도가 된다. 공식을 외우거나 유도할 때 0이나 1의 값을 잘 이용하면 쉽게 외우고 유도할 수 있다. 행렬에서 왜 3x3 행렬이 아니고 4x4 행렬이냐고 생각할 수 있다. 수학적인 표기를 깔끔하게 하기 위해서 4x4로 표기했을 뿐이고, 실제 계산에선 3x3으로 계산하거나 더 단순하게 계산한다. 행렬은 표기법일 뿐이고 실제 계산은 덧셈, 뺄셈, 곱셈, 나눗셈의 조합이라는 것을 명심하자.
물리학에선 단위 일치가 중요하다. 컴퓨터 게임 속 세상에선 우리가 사용하는 초, 미터, 킬로그램 단위를 사용하지 않는다. 컴퓨터 게임에선 단위 시간이 1/30초(프레임 시간)이다. 또는 더 섬세하게 나누어서 1/90초로 할 수도 있다. 그림 그리는 시간의 3배 밀도로 물리 시뮬레이션을 할 수 있다. 컴퓨터 게임 속 공간에선 1pixel(화소)가 거리 단위다. 컴퓨터 게임 속에선 질량 단위는 그냥 정수 1이다. 정밀한 위치 계산을 위해서 힘, 가속도, 속도, 위치는 모두 실수로 표현한다. 최종 화면 표시되는 위치는 정수로 변환 되겠지만 내부적인 물리 계산은 실수로 해야 한다. 물리 현상을 시뮬레이션 하는 절차를 위의 그림에서 나타낸 것이다. 간단한 예로 자동차나 로켓이 있다고 하자. 얼마나 멀리 가는지는 연료 통에 비례한다. 얼마나 빨리 가는지는 엔진의 크기와 연료 공급량에 비례한다. 여기서 힘이 나오기 때문이다. 아무리 힘이 좋아도 무게가 많이 나가면 느리다. 고로 실제 가속도는 힘에서 질량을 나누어 주어야 한다. 가속도에 의해서 속도가 점점 빨라진다. 속도가 빨라지면 이동 거리가 늘어난다. 이런 계산을 1/30초마다 한다. 즉, dt(델타 타임) 동안 힘에서 가속도를 구하고, 현재 속도에 가속도를 더하고, 현재 위치에 속도를 더해서 최종 위치를 얻는다. 물리 공식을 그대로 사용하지 않는 이유는 물리 공식이 통제된 실험 상황에서 이상적인 조건을 만들어 실험한 결과를 수식으로 묘사하기 때문에 현실 세계에 그대로 적용할 수 없기 때문이다. 현실 세계에선 진공이 아닌, 공기 저항이나 바람이 있고, 탄성, 마찰 등이 존재한다. 즉, 이런 것들은 이론적으로 값을 구할 수가 없다. 실험에 의해서 구해야 하는 값들이다. 바람이나 공기 저항은 물체와 공기 사이에서 결정 되지 물체 스스로의 속성이 아니다. 탄성과 마찰도 물체와 물체 사이의 관계에서 나오는 것이지 어느 한 물체의 속성으로 스스로 결정할 수 없다.
보통 위의 2가지 경우만 확실하게 이해하면 물리 감각이 있는 것이다. 진공 중에서 무한히 이동하는 등속 운동과 중력 가속도처럼 일정하게 가속을 하는 등가속 운동 2가지만 이해하면 1차원 운동은 이해한 것이다. 진공 중에선 어떤 외부 힘도 없다. 고로 가속도도 없다. 일정한 속도로 이동만 한다. 고로 이동 거리는 속도와 시간을 곱하면 나온다. 진공 중에 중력에 의해서 당겨질 때는 등가속 운동이 된다. 힘이 일정하다는 뜻이고, 고로 가속도도 일정하다. 가속도가 일정하면 속도가 시간에 따라 직선으로 증가한다. 가속도란 속도에 더해지는 속도란 뜻이다. 고로 속도는 단순히 시간과 가속도를 곱하면 얻어진다. 이렇게 등가속 운동을 하는 경우는 속도가 점점 빨라지기 때문에 거리가 제곱 배로 증가한다. 거리는 속도와 시간을 곱한 후에 1/2을 해야 얻는다. 이 관계가 고등학교 수학의 미분 적분에 해당한다. 상수를 적분하면 직선이 되고, 직선을 적분하면 2차 다항식이 된다. 반대로 2차 다항식을 미분하면 1차 다항식인 직선이 되고, 직선을 미분하면 상수가 나온다. 자동차와 로켓의 경우도 등가속 운동으로 근사시킬 수가 있다. 연료 공급량이 일정하기 때문에 나오는 힘도 일정하고, 가속도도 일정하게 된다. 현실 세계에선 가속도도 상수가 아니라 직선이나 곡선으로 변하기 때문에 미분과 적분을 사용하지 않고는 이론적으로 정확한 순간 속도와 순간 위치를 구하지 못 한다. 그렇게 때문에 물리 공식을 시뮬레이션에 사용하지 않고 단순한 반복 계산을 한다.
2차원과 3차원 운동을 실제로 어떻게 묘사하는지 나타낸 그림이다. 포물선 운동을 예로 든 것이다. 2차원이면 2차원 벡터로, 3차원이면 3차원 벡터로 힘, 가속도, 속도, 위치를 나타내고 단순히 더하기만 하면 된다. 물리학 시간에 배운 물리 공식들은 특별한 조건에서만 통하는 수식이다. 지공 중이라든가, 등속, 등가속 등의 조건이 붙는다. 컴퓨터 게임에선 풍력, 마찰력, 중력, 추진력 등 모두 등장하기 때문에 그런 공식을 사용할 수 없다. 위의 그림에서 먼저 현재 물체에 미치는 힘을 결정한다. 대포의 경우는 추진력이 없다. 로켓의 경우는 추진력이 있을 것이다. 그리고 외부에서 바람이 분다. 그리고 공기 마찰력이 있다. 공기 마찰력은 물체의 형상과 관련이 있다. 물체의 이동 방향에는 정반대이며, 그 힘은 물체의 속력(속도의 크기)에 비례한다. 고로 바로 이전 속도를 이용해야 한다. 그리고 중력이 작용한다. 모두 등가속도 운동으로 해결할 수 있다. 여기서 이렇게 합산한 힘에서 질량을 나누어야 비로소 가속도가 구해진다. 그런데 중력 가속도는 질량 나누기 없이 바로 구할 수 있기 때문에 힘에서 계산하지 않고 가속도 계산에 바로 추가할 수 있다. 풍력의 경우는 풍속을 구한 후에 공기 저항과 같은 방식으로 힘을 구한다. 여하튼 이렇게 해서 순간 가속도를 구했다면 이것을 속도에 추가하고, 순간 속도를 구했다면 이것을 위치에 추가한다. 벡터 덧셈이기 때문에 계산이 간단하다. 이런 식으로 해서 실제 물체의 이동을 시뮬레이션 할 수 있다. 외부에서 사람이 주는 명령과 인공 지능이 주는 명령은 힘에 반영되거나 가속도에 반영 되는 형태다. 때로는 속도에 반영하기도 하는데 그러면 갑자기 방향 전환이 가능해지기 때문에 사실성이 떨어진다. 관성 효과나 마찰력 효과를 넣으려면 힘이나 가속도를 제어하는 것이 낫다. 비탈을 내려오는 공을 묘사하려고 한다면 마찰력을 계산해 주어야 한다. 마찰력은 표면의 수직항력에 비례하며, 방향은 이동 방향의 반대이다. 마찰계수는 접촉하는 두 물체의 표면 상태에 따라 다르기 때문에 실험적으로 구해야 한다. 공기 저항이 물체의 형상과 공기 밀도와 관계 있는 것과 마찬가지다. 이런 값은 실험적으로 구해야 하는 것이고, 게임 세계에선 적당한 값으로 설정해 준다.
에너지는 게임 물리 시뮬레이션에 별로 도움 되지 않는다. 몰라도 지장 없다. 반면에 충돌과 관련 있는 운동량과 충격량은 게임 시뮬레이션에 밀접한 도움을 준다. 충돌 순간에 운동량 변화가 있는데 그 양을 충격량이라고 한다. 문제는 현실 세계에선 충돌 시에 탄성 계수에 따라서 에너지 흡수가 일어난다. 탄성 계수는 물체와 물체 사이에서 결정 되기 때문에 실험을 통해서 얻어야 한다. 게임에선 보통 충돌 후에 속도 감소 비율로 정하면 된다. 완전 탄성 충돌에선 운동량 보존 법칙과 에너지 보존 법칙이 성립한다. 고로 에너지 보존 법칙과 운동량 보존 법칙을 이용해서 충돌 후의 물체의 속도를 계산할 수가 있다. 포물선의 경우 수평 방향의 속도는 일정하기 때문에 수평 방향의 운동 에너지는 일정하다. 수직 방향의 운동 에너지는 중력에 의한 잠재 에너지와 보존 법칙이 성립된다. 수직과 수평 방향은 직각을 이루기 때문에 피타고라스 정리에 의해서 수평 수직 성분의 속도에서 구한 운동 에너지를 합하면 대각의 속도로 구한 운동 에너지와 같게 된다. 오직 직각일 때만 통한다. 완전 탄성 충돌이라고 가정하자. 같은 크기에 같은 질량의 공들이 있을 때 어느 한 공이 와서 치면 그 공은 멎고, 힘이 전달되어 끝에 있는 공이 튀어나가는 것을 보았을 것이다. 이 경우 운동하던 공은 정지하던 공의 관성을 받은 것이고, 정지한 공은 운동하던 공의 관성을 받은 것이다. 질량이 같다면 이렇게 대등한 교환이 가능하다. 만약 접촉 지점이 약간 어긋나서 빗맞을 경우 충돌 후의 두 공의 각도와 속력을 구할 수 있을까? (^^) 회전하는 물체의 경우는 반지름에 따라서 실제 속도가 차이가 난다. 허나 각도만 보면 차이가 없다. 이런 물체의 경우도 접선 방향에선 기존의 운동량과 속도, 가속도 공식이 성립 된다. 실제 충돌 시에는 접선 방향의 속도가 회전에 영향을 주게 된다. 단지 각속도, 각가속도란 것을 도입해서 반지름을 곱해야 한다는 것이 추가 되었다. 게임에선 별로 도움이 되지 않는 표현이다. 그런데 토크라는 것은 실제로 도움이 된다. 같은 힘이라도 반지름에 따라서 효과가 다르기 때문에 꼭 알아야 하는 것이 토크 개념이다. 저울의 원리를 시뮬레이션 하려면 토크를 알아야 한다.
몇 가지 단순한 충돌에 대한 계산이다. 탄성 계수가 0이거나 1인 경우는 매우 이상적인 경우로 이 세상에 존재하지 않는 경우이다. 그러나 수식을 이해하기 위해 편리한 경우다. 탄성 계수가 0이란 얘기는 공을 벽에 던지면 벽에 탁 붙어 떨어지지 않는 경우다. 탄성 계수가 1이란 얘기는 벽에 공을 던지면 거울 반사하여 그대로 반대로 튀어 나오는 경우다. 무한 질량을 가지고 있어 움직이지 않는 벽을 향해 공을 던진 경우를 계산한 것이 위의 그림이다. 수직 벽과 수평 벽의 경우 계산이 간단하다. 방향만 바꾸어 주면 된다. 좀 더 일반화 해서 임의의 각도로 누워 있는 벽에 공을 던진 경우이다. 이 경우 법선 벡터를 구해야 한다. 법선 벡터를 구한 후에 이 법선 단위 벡터 방향의 성분을 뽑기 위해서 내적을 구해야 한다. 이렇게 구한 법선 벡터의 2배를 가지고 계산하면 쉽게 반사 방향의 속도를 구할 수가 있다. 이것은 2D와 3D에 모두 적용 가능하다. 3D에선 표면 법선을 구하기 위해서 외적을 구해야 한다. 또 다른 경우로 질량이 같은 공이 축을 맞추어 충돌하는 경우이다. 빗맞는 경우나 질량이 다른 경우는 계산이 복잡하다. 탄성 계수 0이면, 두 공이 붙어서 함께 이동한다는 뜻이다. 함께 이동하는 속도를 구하려면 운동량 보존 법칙과 에너지 보존 법칙을 이용해야 한다.
충돌 전 운동량1 = 질량 x 속도1
충돌 전 운동량2 = 질량 x 속도2
충돌 후 운동량3 = 2 x 질량 x 속도3
운동량3 = 운동량1 + 운동량2
속도3 = (속도1 + 속도2)/2 = 평균 속도
충돌 전 에너지1 = 1/2 x 질량 x 속도1 x 속도1
충돌 전 에너지2 = 1/2 x 질량 x 속도2 x 속도2
충돌 후 에너지3 = 질량 x 속도3 x 속도3
에너지3 = 에너지1 + 에너지2
속도3 x 속도3 = (속도1 x 속도1 + 속도2 x 속도2)/2
위의 계산 결과를 보면 알겠지만 운동량 보존 법칙과 에너지 보존 법칙을 동시에 만족하지 못 한다. 공식에선 최종 속도가 같아야 한다는 것만 알려 주지 어떤 속도인지는 알려 주지 않는다. 탄성 계수 0에선 계산이 이상하다. 반대로 탄성 계수 1에선 두 공이 충돌하면 서로의 속도를 교환하게 된다. 공식이 알려 주는 정보는 충돌 전의 속도 차이와 충돌 후의 속도 차이가 같아야 한다는 것뿐이다. 여기에 운동량 보존 법칙과 에너지 보존 법칙을 적용하면 두 공은 서로의 속도를 교환했다는 것을 알 수 있다. 이런 공식으로는 충돌 현상을 시뮬레이션 하기 어렵다.
좀 더 일반적인 상황을 생각해 보자. 임의의 각도로 서로 충돌하는 두 물체가 있다. 충돌 순간에는 충돌 면이 결정되고, 그 면에 수직인 법선 면도 결정이 된다. 이 때 아주 짧은 시간의 접촉이 있고, 이 시간에 작용 반작용의 힘을 서로에게 준다. 작용 반작용은 법선 방향으로 작용한다. 서로 크기는 같고 반대 방향이다. 이 짧은 시간과 힘을 곱한 것이 충격량이다. 두 물체는 같은 시간 접촉을 했고, 작용 반작용의 원리에 따라서 같은 충격량을 받는다. 문제는 이 충격량이 그대로 운동량에 반영 되는 것이 아니라는 점이다. 완전 탄성체의 경우 이 충격량은 운동량에 그대로 반영된다. 고로 충돌 전후의 운동량 변화량은 충격량과 같다. 물론 완전 탄성체는 이 세상에 없다. 물체가 딱딱하지 않고 약간 부드러운 물체라면 충격량의 일부는 물체의 형상을 변형하는데 이용되고 나머지가 운동량 변화에 영향을 주게 된다. 고로 현실 세계에선 충격량은 운동량에 그대로 반영되지 않는다. 물체가 충돌할 경우의 충격량을 이론적으로 계산하기는 거의 불가능하다. 실험으로도 구하기 어렵다. 가속도계를 장착해서 아주 짧은 시간에 가속도 변화를 측정할 수는 있으나 물체의 질량을 곱해야 힘이 되기 때문에 정확하지 않다. 그래서 완전 탄성체로 가정하여 계산하면 충격량은 운동량 변화에 그대로 반영되고, 충돌 전후의 운동량에는 변화가 없다. 여기서 운동량 보존 법칙이 나타나는데, 운동량 보존 법칙이 성립하려면 완전 탄성체 충돌이어야 한다. 이 경우 운동 에너지도 보존이 된다. 현실 세계에선 변형과 열에너지로 소모되기 때문에 충돌 결과를 예측하기 어렵다. 계산을 간단하게 하기 위해서 게임에선 완전 탄성체로 충돌을 묘사한다. 충돌 면을 구하고 법선 방향의 운동량 성분만 뽑아서 운동량 보존 법칙과 운동 에너지 보존 법칙을 적용한다. 이 두 법칙을 적용하려면 완전 탄성 충돌이어야 한다. 탄성 계수가 1이 아닌 경우에 이 두 법칙을 적용하면 당연히 틀린다.
이론적으로 구한 공식은 현실 세계에 그대로 적용할 수 없다. 그래서 계산이 쉽도록 이상적인 조건에서만 공식을 적용한다. 앞에서 예로 보인 움직이지 않는 벽과 바닥에 대한 충돌은 무한 질량을 가진 물체와 충돌하는 것과 같다. 이 경우 충돌하는 물체만 신경 쓰면 되기 때문에 간단하게 탄성 계수를 적용할 수 있다. 속도만 조금 감속시키면 된다. 당연히 운동량과 운동에너지는 손실이 있고 운동량, 에너지 보존 법칙은 적용할 수가 없다. 또한 다른 질량의 물체 간의 완성 탄성체 충돌에선 운동량-에너지 보존 법칙을 이용했다. 만약 두 물체가 질량도 같다면, 탄성 계수를 적용할 수 있다. 앞에서 탄성 계수가 들어간 이상한 공식을 보았을 것이다. 질량이 같은 공이라면 충돌 면의 법선 방향에 대해서 상대방의 운동량을 그대로 전달 받는다. 완전 탄성체의 경우 충돌 전후의 상대 속도가 같아진다. 질량이 같고 재질이 같으면 속도 감속도 비슷한 비율로 일어날 것이다. 여하튼 여기의 수식으론 컴퓨터 속의 일반적인 충돌 현상을 시뮬레이션 할 수 없다. 기본적으로 충돌 지점에서 발생하는 충격량을 산출하기 어렵다. 완전 탄성체로 가정하고 운동량-에너지 보존 법칙으로 충돌 후 속도를 구한 후에 그 속도에 탄성 계수를 적용해서 감속을 하는 방법 외엔 없다. 완전 탄성 충돌이 아니라면 운동량 보존 법칙이나 에너지 보존 법칙을 적용할 생각을 하지 말아야 한다. 앞에서 다룬 모든 충돌은 모두 완전 탄성 충돌이었다. 위의 탄성 계수가 들어간 공식은 질량이 다른 물체 사이에 통한다는 보장이 없다. 또한 충돌 면의 법선 방향에 대해서만 적용 된다.
공이 2개 있고 충돌 순간의 법선 성분만 다음과 같은 식으로 계산할 수 있다. 두 공의 충돌 후 속도를 계산하려면 2개의 방정식이 필요하다. 운동량 보존 법칙과 운동 에너지 보존 법칙이다. 이 둘을 적용하려면 완전 탄성 충돌을 가정해야 한다. 탄성 계수가 들어 있는 위의 공식은 질량이 같을 경우에만 적용한다.
두 공의 질량 : m, n
충돌 전 속도 : v for m, w for n
충돌 후 속도 : x for m, y for n
완전 탄성 충돌 가정! 탄성 계수 = 1
운동량 보존 법칙 : m*v + n*w = m*x + n*y = h
에너지 보전 법칙 : m*v*v + n*v*v = m*x*x + n*y*y = k
치환법 적용 : x = (h - n*y)/m
치환 정리 : (n*n + m*n)*y*y - 2*n*h*y + h*h - m*k = 0
계수 a = (n*n + m*n)
계수 b = -2*n*h
계수 c = h*h - m*k
2차 다항식 : a*y*y + b*y + c = 0
근의 공식 : y = (-b±√(b*b-4*a*c))/(2*a)
충격량 : m*x - m*v = -(n*y - n*w)
법선 성분의 계산이 끝난 후에 탄성 계수를 적용해서 속도 감속을 시킬 수가 있다. 감소된 속도는 감소된 에너지와 운동량이 된다. 이것은 물체의 변형과 열에너지로 소모된다. 충돌 면의 접선 성분은 회전에 영향을 준다. 회전은 마찰에 의해서 생기는데 마찰력은 법선 성분의 힘에 비례한다. 역시 법선 성분을 먼저 계산해야 한다. 여기서 충격량을 계산하고 접촉 시간을 대충 나눈 후에 힘을 구하면 마찰력을 구할 수 있다. 마찰력은 접선 성분이기 때문에 공의 회전으로 반영이 된다. 고로 접선 성분도 운동량과 에너지 손실이 있다. 여기서 탄성 계수와 마찰 계수를 이론적으로 결정하기는 어렵다. 실험적으로 구하는 것도 한계가 있다. A물체와 B물체 사이에 존재하는 계수들이라서 모든 물체의 쌍으로 실험을 해야 한다. 불가능하다. 게임 속의 탄성 계수와 마찰 계수는 물리 이론에서 말하는 것과 다를 수 있다. 탄성 계수란 단순히 속도 감소율(가속도)이 되고, 마찰 계수 또한 속도 감소율(가속도)로 취급 될 것이다.
보통의 물체는 직접 접촉을 통해 힘과 에너지를 전달하는데 신기하게 직접 접촉 없이 힘과 에너지를 전달하는 것이 있다. 중력, 자기력, 전기력, 빛이다. 인력(당기는 힘), 척력(밀어 내는 힘), 광원의 밝기는 거리에 따라 변한다. 원리가 같기 때문에 광원의 경우로 설명한다. 우주에서 행성의 인력을 계산할 때는 행성과의 거리가 멀기 때문에 점 광원처럼 취급한다. 이 경우는 거리의 제곱에 반비례한다. 거리가 멀어지면 넓어진 면적에 힘과 빛이 나누어지기 때문이다. 이것은 원통 좌표계에 해당 되고 거리가 멀어지면 원의 표면 넓이가 커지는 것과 같다. 무한 길이의 선 광원의 경우는 거리에 반비례한다. 이 것은 원통 좌표계에 해당 되고 거리가 멀어지면 원통의 표면적이 넓어지는데 원의 반지름과 원의 둘레와 관계와 같다. 이런 경우를 현실 세계에서 보긴 힘들다. 무한 넓이의 면 광원은 지구 표면의 중력과 같은 경우다. 높이에 따라 중력이 변하지 않는다. 물론 아주 높이 올라가면 점 광원으로 계산해야 하지만 대기권 안의 세계에선 땅이 평평한 무한 면과 같이 취급된다. 고로 높이와 상관 없이 중력 가속도는 일정하다. 여기서 힘이란 입자 하나에 미치는 힘(가속도)이다. 고로 질량이 곱해져야 한다. 자기력이라면 단위 자석, 전기력이라면 전자 하나가 입자에 해당 된다. 중력이라면 단위 질량이다. 인력과 척력은 원리만 알면 계산이 쉽기 때문에 이것으로 마무리한다.
부력은 물위에 뜨는 물체에 사용하는 단어고, 양력은 하늘에 뜨는 물체에 사용하는 단어이다. 원리는 같다. 물체의 부피를 계산한 후에 그 부피에 해당하는 물, 공기의 질량을 계산해야 한다. 저울의 원리에 의해서 같은 자리를 차지하려고 하는 물, 공기와 물체의 중력 대결에서 물체가 이기면 가라 앉고, 물체가 지면 뜨게 된다. 즉, 물과 공기가 물체보다 더 무거우면 물체가 뜨게 된다는 말이다. 이렇게 해서 부력과 양력을 계산한 후에 물체의 질량을 나누면 가속도가 나온다. 가속도에서 속도를 구하고, 속도에서 물과 공기의 마찰 저항을 계산하면 동작을 묘사할 수 있다. 물과 공기의 마찰 저항은 물체의 형상에 관련 있어 실험적으로 구해야 한다. 물체의 모양이 복잡하면 물체의 부피를 계산하기 어렵다. 보통, 공, 원통, 상자 형태를 사용하는 이유는 계산이 간단하기 때문이다. 물의 밀도는 깊이에 따라 크게 변함이 없다. 공기의 밀도는 높이에 따라 변한다. 수압과 기압은 부력과 상관이 없다. 수압은 깊을수록 커지고, 기압은 높을수록 낮아진다. 이것은 그 위의 물과 공기의 무게로 인한 것이고 부력이나 양력과는 상관 없다. 공기는 압축이 가능하기 때문에 기압이 높으면 밀도도 높아지지만 물은 압축이 되지 않기 때문에 수압이 높아도 밀도가 높아지지는 않는다.
회전이 있는 물체에 대해서 각운동량과 토크라는 개념이 도입 되는데, 거기에는 이유가 있다. 저울을 생각해 볼 때 무게가 무거운 쪽이 땅으로 당기는 힘이 더 강함에도 팔 길이가 짧다는 이유로 가벼운 쪽과 균형을 이룬다. 이 현상을 설명하기 위해서 토크라는 개념이 도입된다. 중력가속도가 질량에 곱해지면 무게라는 힘이 나타난다. 이 무게와 저울 팔의 길이와 묘한 관계가 있음을 파악하고 수식으로 만들면 그것이 토크의 개념이다. 뒤트는 힘에 대해선 토크 개념을 사용해야 한다. 반대로 어떤 물체(사냥감)를 두 사람이 지고 간다고 했을 때 무게 분산은 어떻게 되는가? 저울의 뒤집어 놓으면 바로 그것이 무게 분산과 같다. 저울의 지지대는 양쪽의 무게를 모두 지고 있다. 힘에는 작용 반작용이 있어 항상 반대의 힘이 균형을 이룬다. 고로 저울을 뒤집으면 그것이 바로 무게 분산 계산과 같다. 시소 게임을 만든다고 했을 때 토크에 관여하는 힘을 어떻게 뽑을까? 중력에서 벡터 분해를 해서 회전 방향의 힘만 뽑아 토크를 계산해야 한다. 그런데 이상한 현상이 있다. 저울에선 균형이 깨지면 한 쪽으로 기울어버린다. 균형이 잡힌 상태에선 저울의 팔이 항상 수평을 이룬다. 잘 생각해 보면 기운 상태로 가만히 있어도 균형이 잡힌 것임을 알 수 있다. 그런데도 저절로 수평을 이루는데 계산을 해 보면 그래야 할 이유는 없어 보인다. 아마도 팔이 기울면 미세하게 저울의 지지 중심의 이동이 있는 모양이다. 두 사람이 시소 위에 서서 서로 앞 뒤로 움직이면서 저울 맞추기 실험을 해 보면 수평을 이루지 않은 약간 기운 상태도 균형을 잡는 것을 알 수 있다.
가속도 0인 등속도 운동은 진공 중의 우주에서 운동이다. 가속도가 상수인 등가속도 운동은 지표면에서 중력에 의한 자유 낙하 운동이다. 이제 가속도가 일정하지 않은 운동에 대해서 다룬다. 스프링 운동, 진자 운동, 오뚝이 운동 같은 것은 가속도가 위치에 따라 변한다. 스프링은 복원력이 작용한다. 복원력은 변위(정상 상태에서 벗어난 위치)에 비례하여 발생한다. 복원력은 힘이기 때문에 추의 질량을 나누면 가속도를 구할 수 있고, 추의 속도에 가속도를 더하면 다음 속도를 구할 수 있다. 위치에 속도를 더하면 다음 위치를 구할 수 있다. 계산 시간은 아주 짧은 1/30초 또는 그보다 짧은 시간(dt)에서 하기 때문에 이 구간에서 힘, 가속도, 속도 모두 짧은 직선으로 취급한다. 미적분에서 적분 계산을 하는 것과 같다. 진자의 운동은 변각에 비례하여 복원력이 작용한다. Sin 함수의 경우 ±45도까지는 거의 직선이기 때문에 변각에 그대로 복원력이 비례한다고 생각하면 된다. 회전 운동이기 때문에 변위를 각도로 나타낼 수 있고, 속도는 각속도로 나타낼 수 있다. 가속도 또한 각가속도로 나타낸다. 각가속도가 복원력이니, 각속도에 복원력을 더하고, 각도에 각속도를 더하면 최종 회전 각이 나온다. 실제 물리 시뮬레이션이 아니기 때문에 복원력에서 질량을 나누어 가속도를 구하는 작업 등은 생략하고 복원력을 가속도로 바로 환산하여 적용한다. 무한 진동을 멈추게 하기 위해서 마찰 효과를 준다. 진동에 의한 스프링의 열 에너지로 에너지 손실이 발생하고, 진자의 공기 마찰 등으로 에너지 손실이 발생한다. 속도가 빠르면 열 에너지 발생이 크고, 속도가 빠르면 공기 저항이 강하다. 고로 결정된 속도에 일정 비율을 곱하면 마찰력에 의한 속도 감속 효과를 줄 수 있다. 일정한 값을 X, Y 방향에서 빼는 방법을 사용하면 방향이 바뀌는 효과가 나타난다. 고로 X, Y 방향에 일정한 비율을 곱해야 방향이 바뀌지 않는다.
마찰 계수를 1로 놓고 비탈에서 미끄러질 때의 가속도 구하는 방법을 간단하게 보자. 중력 가속도 G(9.8)를 경사 면에서 수직으로 분해하기 때문에 수평과 수직 방향의 힘의 크기를 벡터 합을 하면 중력 가속도 G가 된다. 마찰 계수가 1이라고 했으니 b의 크기가 바로 마찰력이다. 속도가 s라고 하면 마찰력의 방향은 s의 반대 방향이다. 속도 s가 0인 정지 상태에선 정지 마찰력을 적용한다. 45도에 미끄러진다고 하자. 그 상태는 |a| = |b|의 상태이다. 계산을 간단하게 하기 위해서 정지 마찰력과 이동 마찰력을 같게 놓자. 질량을 1로 놓아서 마찰력과 마찰 감속도를 같게 보자. 일단 기존 속도 s에 비탈을 따라가는 방향의 가속도 a를 더한다. 방향과 무관하게 속력 |s|가 마찰 감속 절대값 |b|보다 작으면 속력을 0으로 한다. 그냥 빼면 부호만 바뀌어 왔다 갔다 계속 떨게 된다. 속력 |s|가 마찰 감속 절대값 |b|보다 크면 속력과 마찰 감속 절대값의 차이를 기존 속도에서 방향을 반대로 하여 뺀다.
s = s - (s/|s|)*|b|
미끄러지는 물체가 회전하는 공이라고 하자. 그럼 회전 속도 w는 얼마로 주어야 할까? 마찰력으로 인해 비탈면을 따라 작용하는 힘의 일부가 회전력으로 작용한다. 몇 %가 회전력으로 전환되는지 알 수 없다. 그래서 이 부분은 고려하지 않고 비탈면을 따라 내려가는 속도 s가 결정 되었다고 했을 때 회전 속도 w를 구하는 방법만 정리한다. 물체의 반경 r과 관련 있다. 바퀴가 굴러 가는 것과 같기 때문에 물체의 반경 r과 비탈면으로 미끄러지는 속도 s로 w를 계산해야 한다. 아주 짧은 순간인 dt, 게임에선 1/30초 동안 비탈면으로 속도 s만큼 이동한다. 물체의 반경이 r이라면 둘레 R = 2*π*r이다. 고로 회전 각도는 s/R*360이 된다. 이것이 회전 속도다.
w = s/(2*π*r)*360
s = w*(2*π*r)/360
반대로 공이나 바퀴에 강력한 회전이 걸려 있다고 하면, 회전력이 속도에 반영된다. 바퀴가 공회전을 하거나 역회전을 하는 경우도 있어서 회전이 바로 이동에 반영되지는 않는다. 바퀴와 지면의 마찰력에 따라서 회전과 이동 사이에 약간의 시간 차이가 있다. 이것을 구현하려면 수직항력을 계산해서 마찰계수를 곱하여 마찰력을 구하고, 이 마찰력이 접선 방향의 회전 저항력이기 때문에, 마찰력에 반지름을 곱해서 토크를 구한다. 토크와 회전 속도와의 관계를 구해야 한다. 각운동량이 소모된 양만큼 접선 방향으로 바퀴가 이동을 하게 된다. 너무 복잡하다.
일단 여기까지 물리 시뮬레이션 구현이 어렵다는 것을 안 것으로 만족하고 게임 엔진들에서 제공하는 물리 엔진을 사용하도록 한다. 몇 가지 함수가 복잡한 계산을 대신 해 준다. 예를 들어 충돌 후의 결과 같은 것이다.
당구는 물리 시뮬레이션을 실습하기 좋은 대상이다. 실제 자연 현상을 그대로 시뮬레이션 할 수는 없다. 어디까지나 흉내 내는 것이다. 충돌에선 완전 탄성 충돌이라고 가정해야 공식의 답을 구할 수 있다. 당구 게임은 수직, 수평 벽을 가지고 있다. 즉, 충돌에서 이상적인 완전 탄성 충돌로 가정하면 반사 각을 아주 쉽게 구할 수 있다. 입사 각도와 반사 각도가 같기 때문에 거울 반사라고 한다. 또한 모든 공이 같은 크기에 같은 질량이다. 고로 완전 탄성 충돌을 가정해서 반사 각과 충격량을 구하기 쉽다. 충격량(운동량 변화량)도 벡터이기 때문에 원래 운동량에 벡터 합을 하면 충돌 후 운동량이 구해진다. 질량이 모두 같기 때문에 운동량은 바로 속도가 되고 충격량은 바로 속도 변화(가속도)가 된다. 완전 탄성 충돌이기 때문에 충돌 전후의 운동량과 에너지 변화는 없다고 본다. 그래서 공끼리 충돌이나 벽과의 충돌에는 일단 완전 탄성 충돌을 가정해서 반사 각과 속도를 구한다. 여기까지 기본 계산이 끝난 후에 현실감을 주기 위해서 마찰 계수와 탄성 계수를 주는데 단순하게 속도 감소율로 대체한다. 그 값은 실험으로 현실과 비슷하게 값을 설정해 준다. 탄성 계수를 적용하지 않아도 된다. 어차피 마찰 계수에 의해서 속도는 점점 줄어든다. 충돌 순간에 속도가 줄어드는 비율이 탄성 계수에 해당 되는데 적용하지 않아도 문제 없을 것이다. 당구라는 것이 가능한 완전 탄성 충돌에 가깝게 만들어진 것이니 속도 감소율은 거의 미미할 것이다.
문제는 스핀(회전)이다. 이 부분을 처리하고자 각운동량과 토크 등을 복잡하게 계산할 필요가 없다. 공의 각운동량을 계산하려면 공 부피에 대해서 적분을 해야 한다. 게임에서 이런 계산을 할 시간이 없다. 공의 크기가 모두 같고 무게가 같기 때문에 각운동량 계산이 단순해진다. 각운동량은 바로 회전 속도가 되어 버린다. 각운동량은 공을 타격할 때 발생한다. 이 것을 수평(팽이 회전)과 수직(바퀴 회전) 회전으로 분해를 해야 하는데 직관적으로 벡터 분해와 같다는 것을 알 수 있다. 공 표면의 한 지점의 속도를 수평과 수직으로 분해 하면 된다. 두 공의 무게가 같기 때문에 운동량에는 속도만 영향을 준다. 수평 스핀은 벽과의 반사에 영향을 준다. 수직 스핀은 공의 속력에 영향을 준다. 공의 표면에 마찰이 없는 이상적인 경우에는 스핀이 서로에게 영향을 줄 수 없을 것이나, 공의 표면에 마찰력이 존재하기 때문에 공끼리의 충돌에서도 서로의 스핀에 영향을 준다. 공이 벽에 충돌 하는 순간에 마찰에 의해서 스핀에 변화가 생긴다. 그 방향이 순방향과 역방향으로 충돌 할 때마다 바뀐다. 순방향 스핀인 경우는 정상적인 거울 반사 각도보다 더 얇게 반사한다. 이런 현상은 탁구 공에 스핀을 넣어 칠 때 확실하게 보인다. 문제는 이 관계를 정확하게 계산할 수 없다는 것이다. 그래서 실험으로 적당하게 흉내 내는 공식을 구한다. 즉, 수평 회전 속도와 반사각의 변화, 수직 회전 속도와 속력 변화의 관계를 대략적인 수식으로 만들어 낸다. 이 부분을 정확하게 물리적으로 계산하기 어려운 이유가 스핀은 마찰력과 관계가 있는데, 마찰력은 충격력에 비례하기 때문이다. 충돌 순간에 충격력을 구하고 거기서 마찰력을 구하여 각운동량에 영향을 주어야 하는데 고등학교 수준의 지식으로는 적절한 물리 공식을 만들기 어렵다. 또한 공이 굴러가는 것은 바퀴가 굴러가는 것과 같아서 기본적으로 이동에는 기본 수직 회전이 들어간다. 물론 또한 바퀴가 헛도는 현상처럼 공의 이동 방향과 회전 방향이 100% 일치하지 않는다.
게임 엔진에서 제공하는 물리 시뮬레이션에서도 완전 탄성 충돌을 기본으로 한다. 완전 탄성 충돌은 표면이 딱딱한 물체(고체/강체 = rigid body)의 충돌이다. 탄성 계수나 마찰계수는 속도 감소율로 간단하게 처리한다. 마찰 계수에 충격력을 곱하면 마찰력이 나오는데 공의 질량이 모두 같기 때문에 1로 처리하면 마찰력은 그대로 감속율이 된다. 이 감속율은 충격력에 비례한다. 충격력은 충격량에서 접촉 시간을 나누어야 하는데 그 짧은 순간의 접촉 시간을 누가 알겠는가? 고로 실제로 이론적으로 구할 수 없는 실험적인 값이다. 그래서 어떤 당구 게임도 실제 당구와 같을 수가 없다. 앞의 글에서 당구 게임을 만들 수 있는 지식은 모두 나열하였다.
출처 : http://blog.daum.net/jty71/15645343
'수학' 카테고리의 다른 글
sin, cos, tan (0) | 2013.05.14 |
---|---|
삼각함수 그래프 (0) | 2013.05.14 |