1. 내적이란?

내적은 두 벡터의 크기와 방향에 대한 관계를 나타내는 연산으로, 결과는 스칼라 값입니다. 이를 스칼라 곱이라고도 합니다.

수학적 정의:
[V1V2=V1V2cosθ\vec{V_1} \cdot \vec{V_2} = |\vec{V_1}| |\vec{V_2}| \cos \theta]

  • ( V1|\vec{V_1}| )과 ( V2|\vec{V_2}| )는 벡터의 크기(길이).
  • ( cosθ\cos \theta )는 두 벡터 간의 각도의 코사인 값.
  • 결과값은 방향을 제거한 크기만 남습니다.

2. 컴포넌트 기반 내적 계산

내적은 벡터의 각 성분을 곱한 뒤 더하여 계산할 수 있습니다.
두 벡터 (V1=(x1,y1)\vec{V_1} = (x_1, y_1)), (V2=(x2,y2)\vec{V_2} = (x_2, y_2))의 내적은 다음과 같습니다:
[V1V2=x1x2+y1y2\vec{V_1} \cdot \vec{V_2} = x_1 \cdot x_2 + y_1 \cdot y_2]


3. 내적의 특징

  1. 결과는 스칼라 값이다.
  2. 내적의 기하학적 의미:
    • 내적이 0이면 두 벡터는 직교(수직)이다.
    • 내적이 양수이면 두 벡터는 예각(90° 미만)을 이루고 있다.
    • 내적이 음수이면 두 벡터는 둔각(90° 초과)을 이루고 있다.
  3. 단위벡터의 내적은 ( cosθ\cos \theta )와 같다.

4. 게임 개발에서 내적의 응용

내적은 주로 게임에서 다음과 같은 상황에 활용됩니다:
1. 프로젝션: 벡터를 특정 축에 투영하여 상대적 위치를 계산.
2. 몬스터 움직임 구현: 마우스 포인터와 몬스터 사이의 거리를 계산하여 몬스터가 가장 가까운 위치로 이동.
3. 각도 계산: 특정 방향으로 벡터가 얼만큼 이동했는지 확인.


5. 코드 분석

5.1. Vector 구조체 내 내적 함수

float Dot(Vector other)
{
    return x * other.x + y * other.y;
}
  • 역할: 두 벡터의 내적을 계산.
  • 구현:
    • 현재 벡터(x, y)와 다른 벡터(other.x, other.y)의 성분끼리 곱하고 이를 합산.

5.2. 몬스터 위치 업데이트

Vector v1 = _end - _start;   // 로밍 경로 벡터
Vector v2 = mousePos - _start; // 마우스와 시작점 간의 벡터
  • 벡터 생성:
    • ( v1\vec{v_1} ): 몬스터의 로밍 경로.
    • ( v2\vec{v_2} ): 마우스 위치와 로밍 시작점 간의 벡터.
v1.Normalize(); // v1을 정규화
float dot = v1.Dot(v2); // v1과 v2의 내적 계산
  • 정규화:
    • 벡터 ( v1v_1 )의 크기를 1로 만들어 방향만 남김.
  • 내적 계산:
    • ( v1v_1 )과 ( v2v_2 )의 내적을 통해 마우스가 로밍 경로에서 얼만큼 떨어져 있는지 계산.
Pos pos = _start + v1 * dot;
if (dot < 0 || dot > maxLength)
{
    return; // 로밍 범위를 벗어난 경우 위치 업데이트 없음
}
_pos = pos;
  • 위치 계산:
    • 로밍 시작점 _start에서 내적 값만큼 이동하여 새로운 위치를 계산.
    • ( dot\text{dot} ) 값이 로밍 범위(0 ~ maxLength)를 벗어나면 위치를 업데이트하지 않음.

5.3. 몬스터 렌더링

Utils::DrawCircle(hdc, _pos, 50); // 몬스터를 원으로 렌더링
Utils::DrawLine(hdc, _start, _end); // 로밍 경로 렌더링
  • 몬스터는 현재 위치(_pos)에서 반지름 50의 원으로 표시.
  • 로밍 경로는 빨간 선으로 렌더링.

6. 게임 구현 결과

  1. 로밍 경로 표시: 화면에 빨간색 선으로 몬스터의 이동 가능 범위를 시각화.
  2. 마우스 포지션 기반 이동:
    • 마우스가 이동할 때마다 내적을 사용하여 몬스터가 가장 가까운 위치로 이동.
    • 범위를 벗어난 경우 이동하지 않음.

7. 내적의 기본 개념 확장

내적(dot product)은 벡터 연산 중 하나로, 특히 다음과 같은 상황에서 강력한 도구로 사용됩니다.

  • 기하학적 의미:
    • 내적은 두 벡터 간의 관계를 정의합니다.
    • (AB=ABcosθ\vec{A} \cdot \vec{B} = |\vec{A}| |\vec{B}| \cos\theta)는 벡터 간 각도 (θ\theta)와 크기 ( A,B|\vec{A}|, |\vec{B}| )를 사용해 내적을 계산.
    • 내적의 값은 ( cosθ\cos\theta )를 통해 두 벡터의 방향성이 유사한지 판단합니다.

중요 정리:
1. (AB>0\vec{A} \cdot \vec{B} > 0): 두 벡터의 방향이 비슷 (예각).
2. (AB=0\vec{A} \cdot \vec{B} = 0): 두 벡터는 서로 직각.
3. (AB<0\vec{A} \cdot \vec{B} < 0): 두 벡터의 방향이 반대 (둔각).


8. 내적을 활용한 프로젝션

내적의 가장 중요한 응용 중 하나는 벡터의 투영(projection)입니다.
어떤 벡터 (B\vec{B})를 (A\vec{A})에 투영할 때:
[투영된 벡터=ABA2A\text{투영된 벡터} = \frac{\vec{A} \cdot \vec{B}}{|\vec{A}|^2} \vec{A}]

  • 투영 길이: (ABA\frac{\vec{A} \cdot \vec{B}}{|\vec{A}|})
  • 이 공식은 방향과 크기를 동시에 보정하여 올바른 투영값을 계산합니다.

9. 게임 내 내적 활용 심화

a. 로밍 범위와 내적 계산

몬스터가 마우스 위치로 이동하는 게임 구현에서 내적은 다음의 두 가지를 해결합니다:
1. 몬스터가 로밍 경로를 벗어나지 않도록 제한:

  • 내적 값 dot이 범위(0 ~ maxLength)를 벗어나면 이동하지 않음.
  1. 로밍 경로에 마우스 위치를 투영:
    • 마우스 위치 벡터를 로밍 벡터에 투영해 가장 가까운 위치를 계산.

구체적 코드 흐름:

Vector v1 = _end - _start;    // 로밍 범위 벡터
Vector v2 = mousePos - _start; // 마우스와 시작점 벡터
v1.Normalize();                // 방향만 남김 (크기를 1로 만듦)
float dot = v1.Dot(v2);        // 내적 계산 (마우스 위치의 투영 길이)
  • (dot): 마우스가 로밍 경로에 투영된 길이(거리).

b. 내적의 기하학적 조건으로 이동 제한

  • (dot<0dot < 0): 로밍 범위 시작점을 벗어남.
  • (dot>maxLengthdot > maxLength): 로밍 범위 끝점을 벗어남.
  • 이 조건을 만족하는 경우에만 이동:
if (dot < 0 || dot > maxLength)
{
    return; // 벗어난 경우 위치를 업데이트하지 않음
}

c. 몬스터의 위치 업데이트

투영 길이 dot를 사용해 새로운 위치를 계산:

Pos pos = _start + v1 * dot; // 시작점에서 dot 길이만큼 이동
_pos = pos;

10. 심화 주제: 내적과 각도 계산

게임에서 캐릭터가 특정 방향으로 바라보게 하거나, 목표 지점을 겨냥하는 데 내적이 자주 사용됩니다.

  1. 벡터 간 각도 계산:

    • 내적과 벡터 크기를 사용해 각도를 계산:
      [cosθ=ABAB\cos \theta = \frac{\vec{A} \cdot \vec{B}}{|\vec{A}| |\vec{B}|}]
    • 이를 통해 두 벡터가 이루는 각도를 구할 수 있음.
  2. 각도를 기준으로 방향 판단:

    • 내적 값이 양수면 목표 방향으로 이동.
    • 음수면 반대 방향으로 이동.
    • ( cosθ=0\cos \theta = 0 )일 경우, 목표 방향을 정확히 바라보고 있음.

5. 강의 심화: 내적과 프로젝션 응용 예제

게임 UI와 환경에서 내적을 활용하는 추가 예제:
1. 서랍 열기:

  • 사용자가 서랍을 정확히 조작하지 못하더라도, 서랍의 이동 경로에 투영하여 자연스럽게 움직임을 보정.
  1. 카메라 방향 보정:

    • 플레이어가 카메라를 특정 방향으로 이동할 때, 내적을 사용해 부드러운 움직임 구현.
  2. 충돌 판정:

    • 두 벡터가 일정 각도 이하일 때만 충돌이 일어나는 조건 계산.

6. 실습: 내적 활용 게임 코드 작성

struct Vector {
    float x, y;

    // 내적 함수
    float Dot(Vector other) {
        return x * other.x + y * other.y;
    }

    // 정규화 함수
    void Normalize() {
        float length = sqrt(x * x + y * y);
        x /= length;
        y /= length;
    }
};

void UpdateMonsterPosition(Vector start, Vector end, Vector mousePos) {
    Vector v1 = end - start;
    Vector v2 = mousePos - start;
    
    v1.Normalize(); // 방향 벡터
    float dot = v1.Dot(v2); // 투영 길이
    
    if (dot < 0 || dot > v1.Length()) {
        return; // 범위를 벗어난 경우
    }

    Vector newPos = start + v1 * dot; // 새로운 위치
    // 몬스터 위치 업데이트
}

profile
李家네_공부방

0개의 댓글