Post List

[실용적 예제로 본 게임 인공지능 프로그램하기] 1. 수학 및 물리학 입문

1. 수학 및 물리학 입문


주목할 만한 몇가지 개념.

책에서는 독자들이 수학이나 물리학을 하나도 모르는 상태를 가정하고 책을 전개 합니다.
따라서 x-y 좌표계와 직선의 방정식 부분부터 시작합니다. 1장에서는 챕터가 진행될수록 자주 쓰이는 특기할만한 개념을 포스팅 하겠습니다.


수학 입문
  • 1. 삼각법 (상대와 나의 각도, 그리고 회전량 등을 표현하는데 자주 쓰인다.)
  • 2. 벡터 (상대와 나의 각도, 거리, 위치, 속도 등을 표현하는데 자주 쓰인다.)
  • 3. 지역공간과 세계공간(local 좌표와 world 좌표)
물리학 입문
  • 4. 속도
  • 5. 가속도
  • 6. 힘


1. 삼각법

"삼각법은 폭 넓은 주제이긴 하지만, 피타고라스 이론과 삼각함수가 이 책의 나머지 부분에서 필요한 내용이다."

 직각은 90도 등 우리는 '도' 단위에 익숙해져 있습니다(degree). 
하지만 수학자들은 degree 대신 라디안(radian)으로 나타내기를 좋아하며 프로그래밍 세계에서도 예외가 아닌듯 합니다. 
라디안은 원점에 중심을 둔 단위 반지름(반경이 1)을 갖는 원에 기초한 측정단위이며 어떤 각 θ 만큼 원의 반지름에서 다음 반지름으로 돌렸을 때의 곡선부분의 길이를 의미합니다.



이제 라디안에 대해 알았으므로 언제든지 degree to radian 변환을 할 수 있습니다.

360° = 2π(rad)
1° = 2π/360(rad)

그 외, 피타고라스 정리와 sin, cos, tan 등의 삼각함수가 있습니다.
Unity의 Mathf.Sin(x) 에서, 우리가 익히 알고있는 sin, cos 그래프 처럼 -1 에서 1 사이의 값을 반환합니다. 그리고 매개변수 x는 rad 단위의 각도를 매개변수로 받습니다.

1
float sinValue = Mathf.Sin(rad);
cs


2. 벡터

"한 벡터 v가 자동차의 속력을 나타낸다고 하자. 벡터의 크기는 자동차의 속력을 나타내고, 방향은 이 자동차가 나아가고 있는 방향을 나타낸다.  이것은 두개의 숫자(x,y)로 나타낼 수 있는 것 치고는 꽤 많은 정보를 담고 있다."

 벡터는 게임 에이전트가 어느 방향으로 총을 발사하는지부터 인공신경망의 입출력을 표현하는 것까지 모든 곳에서 사용됩니다.

여러개의 벡터를 더하고, 빼서 하나의 벡터로 만들 수 있습니다. 이는, 어떤 물체를 움직일 힘(힘은 마찰힘, 가속힘 등 여러 힘이 있다.)들을 합쳐서 하나의 속도를 정할 수 있다는 것을 의미합니다.

벡터에 상수 k를 곱할수 있습니다.
v(2, 3) * k = v(2k, 3k) 를 의미합니다.

벡터의 크기는 그 벡터의 원점부터 종점까지의 길이를 의미합니다. 이를 좌표계에 옮기면 피타고라스의 정리를 사용해서 길이(즉, 크기)를 구할 수 있습니다.

벡터의 정규화 란, 한 벡터 v방향은 유지하지만 크기는(즉, 길이) 1인 단위길이가 되도록 재계산 하는것을 의미합니다.
벡터의 정규화가 사용되는 예로, 어떤 축구선수가 자신의 속도벡터로부터 패스를 할 방향을 계산하여야 합니다. 이때 축구선수가 패스할수 있는 힘의 크기는 상황에따라 다르겠지요. 이때, 방향벡터를 구하기 위해 속도벡터를 정규화 하여 방향만 꺼내고, 힘의크기를(상수) 곱하여 패스되는 공의 속도를 구할 수 있습니다.

벡터의 내적은, 두 벡터 사이의 각을 구하는데 사용됩니다. 또한, 나의 방향벡터와 상대의 방향벡터를 내적하면 상대가 나를 마주보고 있는지 아닌지를 구하는데에도 쓰입니다. 그리고 나의 대면벡터(facing vector)와 나와 상대까지의 벡터의 내적은 그 상대가 어디에 위치해있는지를 알 수 있게 합니다. 양수이면 나의 앞에, 음수이면 나의 뒤에 있음을 알려줍니다. 


3. 지역공간과 세계공간

 게임에서 월드좌표와 로컬좌표가 있습니다. 만약 어느 에이전트가 "3시방향 50m 적 출현" 이라고 전보를 보냈다면, 3시방향은 에이전트 자신의 기준으로 3시방향이며 50m전방임을 의미합니다. 


4. 속도

속도의 기본 단위는 m/s 입니다. 즉, 속도 = 거리/시간 이라는 등식이 성립합니다.
만약 시간 t에서 P의 위치에서 항속도 v로 이동하는 자동차가 있다면, 다음 Update때의 위치는 P(t+1) = P(t) + v가 될 것입니다.
요즘 게임은 렌더링, 물리법칙 등의 Update 시간간격을 다르게 합니다. 그러므로 속도의 기본단위에서 s는 '초'가 아닌 '시간간격'이 될 수도 있음을 인지해야 합니다.

5. 가속도

가속도는 '시간에 따른 속도의 변화율' 을 표현하는 벡터량이고, 초당 미터로 측정되며 기본단위는 m/s² 입니다.  중, 고등학교때 배운 바로 시간에 대한 속도의 직선방정식은 

v = u + at (단, v는 다음속도, u는 현재속도, a는 가속도, t는 시간) 

에서 기울기에 해당하는 a가 바로 t시점에서의 가속도 입니다.
예제로 초기 3m/s의 속도로 움직이기 시작하여 2m/s²로 가속하는 자동차의 3초후의 속도는
 v = 3m/s + 2m/s² * s
v = 9m/s

따라서 3초후의 속도는 9m/s 입니다.

가속도 부분이 중요한 이유는 가속도 그래프의 y축(속도) 와 x축(시간), 그리고 그래프의 모양을 알면 원하는 기간만큼의 에이전트가 움직인 거리를 구할 수 있기 때문입니다.

만약 그래프의 아랫부분이 직사각형 꼴 이라면
넓이 = △t * u 
만약 그래프의 아랫부분이 삼각형 꼴 이라면
넓이 = 1/2 * △t * u 
의 식으로 나타내어질 수 있습니다.

출처 : http://study.zum.com/book/13471
사각형의 넓이와 삼각형의 넓이를 합한다면 0~t 까지 이동한 거리를 알수 있겠죠. 즉,

넓이 = △t * u + 1/2 * △t * (v - u) 
v - u = △v = a△t 이므로
넓이 = △t * u + 1/2* a△t²

의 식을 구할 수 있습니다. 또한,

△t = (v - u) / a 이므로
넓이 = u * ( (v - u) / a ) + ( 1/2 * a * ( ( v - u ) / a )² )
v² = u² + 2 * a * 넓이

의 식 또한 구할 수 있습니다.

6. 힘

단일 물체에 가해지는 힘이 여러 종류의 힘 이라면, 결국 물체가 움직이는 방향과 힘은 "여러종류의 힘이 합해진 어떤 힘" 일 것입니다. 
물체에 작용하는 힘들의 합이 0 이 아니라면, 그 힘의 방향으로 가속도가 전해질 것입니다. 이때 유명한 식이 있습니다.

F = m * a 

이 식으로 물체의 다음 위치와 속도를 갱신할 수 있게 됩니다.

1
2
3
4
5
6
public void ForceAndPosition(float time, float force)
{
    Vector2 acceleration = force / mass;
    Vector2 newVelocity = lastVelocity + acceleration * time;
    Vector2 newPosition = lastPosition += velocity * time;
}    
cs




요약

 이 챕터를 공부하며 깨달은것은, 학창시절을 보내며 공부해왔었던 (그러나 지금은 기억에서 대부분 잊힌) 물리학 법칙과 수학 공식들이 게임 프로그래밍에 쓰이고 있고 비록 이 원리들은 Unity에서 메소드로 구현되어 있더라도 그렇지 않은 엔진들도 있을 것이며, 실세계의 법칙들이 게임에 적용된다는것 입니다.

 게임 인공지능 프로그래머가 되기 위해 일단 게임 물리학과 게임 수학을 더 공부해야 함을 느끼게 되는 계기가 되었습니다. 









댓글

댓글 쓰기