내적은 두 벡터의 크기와 방향에 대한 관계를 나타내는 연산으로, 결과는 스칼라 값입니다. 이를 스칼라 곱이라고도 합니다.
수학적 정의:
[]
내적은 벡터의 각 성분을 곱한 뒤 더하여 계산할 수 있습니다.
두 벡터 (), ()의 내적은 다음과 같습니다:
[]
내적은 주로 게임에서 다음과 같은 상황에 활용됩니다:
1. 프로젝션: 벡터를 특정 축에 투영하여 상대적 위치를 계산.
2. 몬스터 움직임 구현: 마우스 포인터와 몬스터 사이의 거리를 계산하여 몬스터가 가장 가까운 위치로 이동.
3. 각도 계산: 특정 방향으로 벡터가 얼만큼 이동했는지 확인.
Vector 구조체 내 내적 함수float Dot(Vector other)
{
return x * other.x + y * other.y;
}
x, y)와 다른 벡터(other.x, other.y)의 성분끼리 곱하고 이를 합산.Vector v1 = _end - _start; // 로밍 경로 벡터
Vector v2 = mousePos - _start; // 마우스와 시작점 간의 벡터
v1.Normalize(); // v1을 정규화
float dot = v1.Dot(v2); // v1과 v2의 내적 계산
Pos pos = _start + v1 * dot;
if (dot < 0 || dot > maxLength)
{
return; // 로밍 범위를 벗어난 경우 위치 업데이트 없음
}
_pos = pos;
_start에서 내적 값만큼 이동하여 새로운 위치를 계산.Utils::DrawCircle(hdc, _pos, 50); // 몬스터를 원으로 렌더링
Utils::DrawLine(hdc, _start, _end); // 로밍 경로 렌더링
_pos)에서 반지름 50의 원으로 표시.내적(dot product)은 벡터 연산 중 하나로, 특히 다음과 같은 상황에서 강력한 도구로 사용됩니다.
중요 정리:
1. (): 두 벡터의 방향이 비슷 (예각).
2. (): 두 벡터는 서로 직각.
3. (): 두 벡터의 방향이 반대 (둔각).
내적의 가장 중요한 응용 중 하나는 벡터의 투영(projection)입니다.
어떤 벡터 ()를 ()에 투영할 때:
[]
몬스터가 마우스 위치로 이동하는 게임 구현에서 내적은 다음의 두 가지를 해결합니다:
1. 몬스터가 로밍 경로를 벗어나지 않도록 제한:
dot이 범위(0 ~ maxLength)를 벗어나면 이동하지 않음.구체적 코드 흐름:
Vector v1 = _end - _start; // 로밍 범위 벡터
Vector v2 = mousePos - _start; // 마우스와 시작점 벡터
v1.Normalize(); // 방향만 남김 (크기를 1로 만듦)
float dot = v1.Dot(v2); // 내적 계산 (마우스 위치의 투영 길이)
dot): 마우스가 로밍 경로에 투영된 길이(거리).if (dot < 0 || dot > maxLength)
{
return; // 벗어난 경우 위치를 업데이트하지 않음
}
투영 길이 dot를 사용해 새로운 위치를 계산:
Pos pos = _start + v1 * dot; // 시작점에서 dot 길이만큼 이동
_pos = pos;
게임에서 캐릭터가 특정 방향으로 바라보게 하거나, 목표 지점을 겨냥하는 데 내적이 자주 사용됩니다.
벡터 간 각도 계산:
각도를 기준으로 방향 판단:
게임 UI와 환경에서 내적을 활용하는 추가 예제:
1. 서랍 열기:
카메라 방향 보정:
충돌 판정:
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; // 새로운 위치
// 몬스터 위치 업데이트
}