왼쪽의 원이 오른쪽으로 움직였다면, 원은 x축으로 dx만큼, y축으로 dy만큼 이동한 것이다.
왼쪽 원의 중심점 좌표를 (cx, cy), 움직인 오른쪽 원의 중심점 좌표를 (cx', cy')라고 한다면, (cx', cy')는 다음과 같이 표현할 수 있다.
cx' = cx + dx
cy' = cy + dy
이때 dx와 dy가 양수인지 음수인지에 따라 원이 이동하는 방향도 달라지게 된다.
dx > 0, dy > 0 --> 원은 우측 상단으로 이동
dx > 0, dy < 0 --> 원은 우측 하단으로 이동
dx < 0, dy > 0 --> 원은 좌측 상단으로 이동
dx < 0, dy < 0 --> 원은 좌측 하단으로 이동
이때 코드를 cx += dx
, cy += dy
로 작성한다면 원이 추가로 생성되는 것이 아닌, 한 원이 이동하는 형태의 그림이 그려지게 된다. 여기서 dx
와 dy
는 방향벡터이다.
다음으로 두 원의 충돌을 처리하는 방법을 생각해 보자.
두 원 사이의 거리를 d라고 한다면, 원의 충돌 여부는 두 원의 반지름의 합과 d의 관계로 판단한다. 원의 중심점 사이 거리 d와 두 반지름의 합이 같아질 때 두 원이 충돌했다고 볼 수 있다.
d는 어떻게 계산할 수 있을까? 먼저 파란색 원의 중심점을 (cx, cy)라고 놓고, 빨간색 원의 중심점을 (dx, dy)라고 놓는다. 여기서도 피타고라스 정리를 적용한다면 로 정리할 수 있다.
이를 코드로 작성하면 아래와 같다.
distance = sqrt(pow(dx-cx, 2.0) + pow(dy-cy, 2.0));
if (distance == r1 + r2) // 충돌한다면...
다음은 벽과의 충돌을 처리해야 한다.
벽과 충돌 여부는 원의 중심점 좌표에서 반지름을 뺀 값과 벽의 관계를 비교해서 판단할 수 있다.
먼저 왼쪽 벽과의 충돌 여부를 판단하려면 중심점에서 반지름 값을 뺀 x 좌표인 cx-r
과 왼쪽 벽 좌표 left
를 비교해야 한다. 만약 cx-r
이 left
보다 작다면 공은 벽에 겹쳐 있거나 벽보다 왼쪽에 위치한다. 또 cx-r
이 left
와 같다면 벽에 맞닿아 있는 것이다.
같은 방법을 오른쪽과 위, 아래 벽에도 적용할 수 있다.
이를 코드로 작성할 때는 메인 함수에서 glutInitDisplayMode()
를 GLUT_DOUBLE
로 설정해 주어야 한다. 공의 움직임을 표현해야 하기 때문이다. 또한 GLUT_DOUBLE
로 설정한 후에는 움직임을 표현하는 함수에 glutSwapBuffers()
함수를 추가해 주어야 한다.