기하학 핵심 정리

기하학(Geometry)은 공간에 존재하는 점, 선, 면, 도형의 형태와 관계를 다루는 수학이다.

게임 개발에서는 단순히 도형의 성질을 공부하는 것보다 다음과 같은 문제를 해결하는 데 사용된다.

좌표
-> 위치 표현

거리
-> 두 객체 사이의 간격

각도
-> 방향과 회전

벡터
-> 이동과 방향

직선 / 평면
-> 충돌과 공간 분할

도형
-> 충돌 영역

교차
-> Raycast / Collision

좌표 변환
-> World / Local / Screen

결국 게임에서 기하학은 게임 월드의 공간을 계산하는 수학이라고 볼 수 있다.

점(Point)은 공간에서 위치를 나타낸다.

2차원에서는

P = (x, y)

3차원에서는

P = (x, y, z)

로 표현한다.

점 자체에는 크기가 없다.

게임에서는

Player Position
Enemy Position
Spawn Position
Target Position

등이 모두 점으로 생각될 수 있다.

좌표계

좌표계는 공간에서 점의 위치를 표현하기 위한 기준이다.

2차원 Cartesian 좌표계에서는

        y
        ^
        |
        |
--------+--------> x
        |
        |

처럼 x, y축을 사용한다.

3차원에서는 여기에 z축이 추가된다.

(x, y, z)

게임 엔진에서는 월드 좌표, 로컬 좌표, 카메라 좌표 등 여러 좌표계를 사용한다.

거리

두 점 사이의 거리는 피타고라스 정리에서 나온다.

2차원에서

A = (x₁, y₁)
B = (x₂, y₂)

라면

distance =
√((x₂-x₁)² + (y₂-y₁)²)

이다.

3차원에서는

distance =
√((x₂-x₁)² + (y₂-y₁)² + (z₂-z₁)²)

이다.

게임에서는

float distance = Vector3.Distance(a, b);

처럼 사용한다.

거리 제곱

실제 거리의 제곱을 사용하면 제곱근 계산을 피할 수 있다.

distance² =
(x₂-x₁)² + (y₂-y₁)² + (z₂-z₁)²

예를 들어

if ((target - player).sqrMagnitude < range * range)
{
    // 범위 안
}

처럼 사용할 수 있다.

거리 비교만 필요한 경우에는 실제 거리를 계산할 필요가 없다.

distance < range

distance² < range²

는 같은 비교 결과를 낸다.

선분

두 점을 연결한 유한한 선을 선분(Line Segment)이라고 한다.

A -------- B

게임에서는 공격 범위, 이동 경로, 충돌 검사 등에 사용한다.

두 점 A, B 사이의 선분 위의 점은

P(t) = A + (B-A)t

로 표현할 수 있다.

0 <= t <= 1이면 선분 내부다.

t = 0 -> A
t = 0.5 -> 중간
t = 1 -> B

이는 게임 개발에서 사용하는 Lerp와 같은 원리다.

직선

직선은 양쪽 방향으로 무한히 이어지는 선이다.

2차원에서는

y = ax + b

처럼 표현할 수 있다.

여기서

a -> 기울기
b -> y절편

이다.

두 점을 알고 있다면 기울기는

a = (y₂-y₁)/(x₂-x₁)

이다.

단, 수직선에서는 x₂-x₁ = 0이므로 일반적인 기울기 표현을 사용할 수 없다.

벡터

벡터(Vector)는 크기와 방향을 가진 값이다.

게임에서는 이동과 방향을 표현할 때 핵심적으로 사용한다.

Vector3 velocity
Vector3 direction
Vector3 acceleration

점과 벡터는 구분할 필요가 있다.

점 -> 위치
벡터 -> 방향과 크기

예를 들어

Player Position = (10, 5)

는 위치이고,

Direction = (1, 0)

은 오른쪽 방향을 의미한다.

벡터의 크기

벡터

v = (x,y,z)

의 크기는

|v| = √(x²+y²+z²)

이다.

방향만 필요하다면 정규화할 수 있다.

정규화

벡터의 크기를 1로 만드는 것을 정규화(Normalization)라고 한다.

v̂ = v / |v|

정규화된 벡터를 단위 벡터라고 한다.

게임에서 방향을 계산할 때 매우 중요하다.

Vector3 direction = (target - position).normalized;

이렇게 하면 방향은 유지하면서 크기는 1이 된다.

내적

두 벡터의 내적(Dot Product)은

A · B =
AxBx + AyBy + AzBz

이다.

또한

A · B = |A||B|cosθ

라는 관계가 있다.

따라서 두 벡터 사이의 각도를 판단할 수 있다.

A · B > 0 -> 같은 방향에 가까움
A · B = 0 -> 수직
A · B < 0 -> 반대 방향에 가까움

게임에서 매우 자주 사용한다.

예를 들어 적이 플레이어의 앞에 있는지 확인할 수 있다.

Vector3 direction = (target - enemy.position).normalized;

float dot = Vector3.Dot(enemy.forward, direction);

if (dot > 0)
{
    // 앞쪽
}

시야각

내적을 이용하면 시야각을 계산할 수 있다.

Forward · Direction = cosθ

따라서

dot >= cos(FOV / 2)

조건을 사용하면 특정 시야각 안에 객체가 있는지 판단할 수 있다.

        Target
          *
        /   \
       /     \
      /       \
     /  FOV    \
    /           \
 Player

AI의 시야 판정에서 대표적으로 사용하는 방식이다.

외적

3차원에서 두 벡터의 외적(Cross Product)은 두 벡터에 모두 수직인 벡터를 만든다.

A × B

크기는

|A × B| = |A||B|sinθ

이다.

방향은 오른손 법칙으로 결정된다.

게임에서는

법선 벡터
회전 방향
평면 방향
삼각형 면 방향

등을 계산하는 데 사용한다.

법선 벡터

평면이나 표면에 수직인 벡터를 법선(Normal)이라고 한다.

삼각형의 두 변을

A
B

라고 하면

N = A × B

로 법선을 구할 수 있다.

그래픽스에서는 매우 중요하다.

Vertex
-> Triangle
-> Normal
-> Lighting

으로 연결되기 때문이다.

각도

두 벡터 사이의 각도는 내적을 이용해 구할 수 있다.

cosθ = (A·B) / (|A||B|)

따라서

θ = acos((A·B)/(|A||B|))

이다.

게임에서는 캐릭터가 적을 바라보는지, 공격 범위 안에 있는지, 회전해야 하는 방향이 어느 쪽인지 등을 판단할 때 사용할 수 있다.

삼각형

삼각형은 가장 기본적인 다각형이다.

세 변의 길이를

a
b
c

라고 할 때 삼각형이 되기 위한 조건은

a + b > c
b + c > a
c + a > b

이다.

삼각형은 3D 그래픽스에서도 기본적인 구성 단위다.

Mesh
-> Vertex
-> Triangle

삼각형의 종류

변을 기준으로 하면

정삼각형
이등변삼각형
부등변삼각형

으로 나눌 수 있다.

각도를 기준으로 하면

예각삼각형
직각삼각형
둔각삼각형

으로 나눌 수 있다.

피타고라스 정리

직각삼각형에서

a² + b² = c²

이다.

여기서 c는 빗변이다.

게임에서 거리 계산의 기본이 되는 공식이다.

2차원 거리 공식 역시 사실상 피타고라스 정리를 확장한 것이다.

dx = x₂-x₁
dy = y₂-y₁

distance² = dx² + dy²

삼각함수

기본적인 삼각함수는

sin
cos
tan

이다.

직각삼각형에서

sinθ = 대변 / 빗변
cosθ = 인접변 / 빗변
tanθ = 대변 / 인접변

이다.

게임에서는 방향과 회전을 계산할 때 사용한다.

각도
-> sin / cos
-> 방향 벡터
-> 이동

라디안

각도를 수학적으로 표현할 때 라디안(Radian)을 사용한다.

180° = π rad
360° = 2π rad
90° = π/2 rad

게임 엔진의 회전 관련 API에서는 라디안 또는 도(degree)를 사용하는 경우가 있으므로 단위를 항상 확인해야 한다.

원은 중심에서 같은 거리에 있는 점들의 집합이다.

중심이 (cx, cy)이고 반지름이 r이면

(x-cx)² + (y-cy)² = r²

이다.

게임에서는 원형 충돌 범위나 탐지 범위 등을 표현할 때 사용할 수 있다.

3차원에서 원을 확장하면 구가 된다.

중심이 (cx,cy,cz)이고 반지름이 r이면

(x-cx)²
+ (y-cy)²
+ (z-cz)²
= r²

이다.

두 구의 중심 거리와 반지름을 비교하면 충돌 여부를 판단할 수 있다.

distance <= r₁ + r₂

이면 두 구가 겹친다.

사각형과 AABB

AABB는 Axis-Aligned Bounding Box의 약자다.

축에 맞춰진 박스 형태의 충돌 영역이다.

2차원에서는

minX <= x <= maxX
minY <= y <= maxY

같은 조건으로 영역을 표현할 수 있다.

3차원에서는

minX <= x <= maxX
minY <= y <= maxY
minZ <= z <= maxZ

를 사용한다.

계산이 단순하기 때문에 충돌 후보를 빠르게 걸러내는 데 유용하다.

OBB

OBB는 Oriented Bounding Box다.

AABB와 달리 객체의 회전에 맞춰 회전할 수 있다.

AABB -> 축에 고정
OBB  -> 객체 방향에 맞춰 회전

OBB는 더 정확하게 객체를 감쌀 수 있지만 계산이 더 복잡하다.

캡슐

캡슐(Capsule)은 선분을 중심으로 일정한 반지름을 가진 형태다.

게임 캐릭터의 충돌 영역으로 자주 사용된다.

   ___
 /     \
|       |
|       |
 \_____/

사람 형태를 단순화하면서도 계단이나 경사면에서 비교적 자연스럽게 움직일 수 있다는 장점이 있다.

평면

3차원 공간에서 평면은

ax + by + cz + d = 0

으로 표현할 수 있다.

여기서

N = (a,b,c)

가 평면의 법선 벡터다.

평면은

바닥
벽
절단면
카메라
클리핑

등의 계산에 사용된다.

점과 평면의 거리

P와 평면

ax + by + cz + d = 0

사이의 거리는

distance =
|ax + by + cz + d|
/
√(a²+b²+c²)

이다.

부호를 유지하면 점이 평면의 어느 쪽에 있는지도 판단할 수 있다.

Ray

Ray는 한 점에서 한 방향으로 무한히 뻗는 선이다.

P ------------------->

수식으로는

P(t) = O + Dt

로 표현한다.

여기서

O -> 시작점
D -> 방향
t >= 0

이다.

게임에서는 Raycast가 대표적인 사용 사례다.

Camera
-> Ray
-> Collision Test
-> Hit

마우스로 월드의 객체를 선택하는 기능도 이런 원리를 사용할 수 있다.

선분과 교차

두 선분이 교차하는지 판단하는 것은 2D 게임에서 자주 등장한다.

A -------- B
     X
    / \
   /   \
  C-----D

교차 여부는 방향성이나 외적을 이용해서 판단할 수 있다.

두 점을 기준으로 다른 점들이 어느 방향에 있는지를 비교하면 선분 교차 여부를 판단할 수 있다.

점과 선분의 최단 거리

P에서 선분 AB까지의 가장 가까운 점을 찾을 수 있다.

먼저

AP = P - A
AB = B - A

를 구하고,

t = (AP · AB) / (AB · AB)

를 계산한다.

그다음 t

0 <= t <= 1

범위로 제한한다.

t = Clamp(t, 0, 1)

가장 가까운 점은

Closest = A + AB * t

이다.

이 방법은 선분과 원의 충돌, 레이저 판정, 거리 기반 판정 등 다양한 곳에 사용할 수 있다.

점과 삼각형

점이 삼각형 내부에 있는지 판단하는 문제도 중요하다.

대표적인 방법으로 Barycentric Coordinate를 사용할 수 있다.

삼각형을

A
B
C

라고 하면 점 P

P = uA + vB + wC

로 표현할 수 있다.

그리고

u + v + w = 1

이다.

일반적으로

u >= 0
v >= 0
w >= 0

이면 점이 삼각형 내부 또는 경계에 있다고 판단할 수 있다.

그래픽스에서 매우 중요한 개념이다.

무게중심 좌표

Barycentric Coordinate는 삼각형 내부의 점을 표현하는 데 사용할 수 있다.

이를 이용하면

Triangle
-> Vertex A / B / C
-> 가중치 u / v / w
-> 임의의 내부 위치

를 계산할 수 있다.

텍스처 좌표, 색상, 법선, 위치 등의 보간에도 사용된다.

볼록과 오목

다각형은 형태에 따라 볼록(Convex)과 오목(Concave)으로 나눌 수 있다.

볼록 다각형에서는

어떤 두 점을 연결해도
-> 선분 전체가 내부에 존재

한다.

오목 다각형은 내부로 들어간 부분이 존재한다.

충돌 판정에서는 볼록 도형이 상대적으로 다루기 쉽다.

Separating Axis

두 볼록 도형이 충돌하는지 검사할 때 사용할 수 있는 대표적인 방법이 SAT(Separating Axis Theorem)다.

핵심 아이디어는

두 도형을 분리할 수 있는 축이 하나라도 존재하는가?

이다.

도형 A
-> 축에 투영

도형 B
-> 같은 축에 투영

투영 구간이 겹치지 않음
-> 충돌하지 않음

반대로 모든 검사 축에서 투영 구간이 겹친다면 충돌한다고 판단할 수 있다.

2D/3D 충돌 검사의 중요한 기반이다.

좌표 변환

게임에서는 하나의 좌표계만 사용하지 않는다.

대표적으로

Local Space
-> Object Space
-> World Space
-> View Space
-> Clip Space
-> Screen Space

등이 있다.

예를 들어

Local Position
-> Transform
-> World Position

처럼 좌표를 변환한다.

로컬 좌표와 월드 좌표

로컬 좌표는 객체 자신을 기준으로 한 위치다.

월드 좌표는 게임 월드 전체를 기준으로 한 위치다.

Local
-> 부모 기준 위치

World
-> 게임 월드 기준 위치

부모 객체가 움직이면 로컬 좌표는 그대로여도 월드 좌표는 변할 수 있다.

회전

2D에서 회전은 삼각함수로 표현할 수 있다.

(x,y)를 원점 기준으로 θ만큼 회전하면

x' = xcosθ - ysinθ
y' = xsinθ + ycosθ

이다.

이를 행렬로 표현하면

[ x' ]   [ cosθ  -sinθ ] [ x ]
[ y' ] = [ sinθ   cosθ ] [ y ]

가 된다.

3D에서는 회전축이 추가되기 때문에

Euler Angle
Rotation Matrix
Quaternion

등을 사용한다.

원근과 투영

3D 공간의 객체를 2D 화면에 표현하려면 투영(Projection)이 필요하다.

대표적으로

Perspective Projection
Orthographic Projection

이 있다.

Perspective는 멀리 있는 객체가 작게 보인다.

Camera
-> 가까운 물체 크게
-> 먼 물체 작게

Orthographic은 거리에 따른 크기 변화를 적용하지 않는다.

Camera
-> 같은 크기 유지

게임의 카메라 종류에 따라 사용한다.

게임 그래픽스와 기하학

3D 그래픽스의 기본 흐름도 기하학과 직접 연결된다.

Model Vertex
-> Local Space
-> World Space
-> View Space
-> Projection
-> Screen Space

여기서

Vertex
Vector
Matrix
Plane
Triangle
Normal
Projection

등의 기하학 개념이 계속 사용된다.

기하학과 충돌

게임의 충돌 판정은 대부분 기하학 문제로 볼 수 있다.

Sphere vs Sphere
-> 중심 거리 비교

AABB vs AABB
-> 축별 범위 비교

Ray vs Object
-> 교차 검사

Point vs Triangle
-> Barycentric Coordinate

Convex vs Convex
-> SAT

Character vs Environment
-> Capsule / Collider

결국 충돌 시스템은 공간에 존재하는 도형 사이의 관계를 계산하는 시스템이다.

기하학과 게임 AI

AI에서도 기하학이 많이 사용된다.

AI Position
-> Target Position
-> Direction
-> Distance
-> Angle
-> Visibility
-> Decision

예를 들어 적이 플레이어를 볼 수 있는지 판단하려면

거리
+
시야각
+
Raycast

를 조합할 수 있다.

기하학과 애니메이션

캐릭터 애니메이션에서도 위치와 회전 계산이 필요하다.

Bone
-> Position
-> Rotation
-> Parent Transform
-> Child Transform

특히 IK(Inverse Kinematics)는 목표 위치를 만족하도록 관절의 회전을 계산하는 문제다.

Target
-> Joint Position
-> Angle
-> Rotation
-> Pose

여기에도 기하학과 삼각함수가 사용된다.

핵심 정리

게임 개발에서 기하학을 공부한다면 우선 다음 개념을 잡는 것이 좋다.

점
-> 위치

좌표계
-> 공간 표현

거리
-> 두 점 사이의 간격

선 / 선분
-> 공간상의 관계

벡터
-> 방향과 크기

내적
-> 각도 / 방향 판단

외적
-> 수직 벡터 / 방향 / 법선

삼각함수
-> 각도 / 회전 / 방향

평면
-> 3D 공간 분할

Ray
-> 방향성 교차 검사

삼각형
-> 3D 그래픽스 기본 단위

원 / 구
-> 거리 기반 영역

AABB / OBB / Capsule
-> 충돌 영역

Barycentric Coordinate
-> 삼각형 내부 좌표 / 보간

SAT
-> 볼록 도형 충돌

좌표 변환
-> Local / World / View / Screen

Projection
-> 3D -> 2D

기하학의 핵심은 공식을 외우는 데 있지 않다.

공간에 존재하는 문제를 수학적인 관계로 바꾸는 것이 핵심이다.

게임 개발에서는 대부분 다음 형태로 나타난다.

게임 월드
-> 점 / 벡터 / 도형으로 모델링
-> 거리 / 각도 / 교차 계산
-> 공간 관계 판단
-> 게임 로직 실행

예를 들어 공격 판정 하나만 봐도

공격자
-> 위치

대상
-> 위치

두 위치
-> 방향 + 거리

방향
-> 내적
-> 시야각 판정

거리
-> 공격 범위 판정

Ray
-> 장애물 검사

Collider
-> 실제 충돌 판정

으로 이어진다.

따라서 기하학은 게임 개발에서 단순한 수학 과목이 아니라 월드의 공간을 컴퓨터가 계산할 수 있는 형태로 표현하는 기반 기술에 가깝다.

선형대수가 공간의 벡터와 변환을 다룬다면, 기하학은 그 벡터와 변환이 실제 공간에서 어떤 관계를 가지는지를 다룬다고 이해하면 된다.