1. 내적
(1) 기하학적 정의 (위키백과)
두 벡터의 크기를 곱하고 cosθ( θ는 두 벡터 사이의 각도 )를 곱한 값.
(2) 정사영(수직사영, 위키백과)
한 벡터를 다른 벡터에 사영하는 것.
(벡터 위에 불을 켜서 그 그림자를 다른 벡터에 가져다대는 것이라고 비유할 수 있다)
여기에서 정사영된 벡터를 구하려면 해당 정사영 값에 단위벡터를 곱해주면 된다.
( c = |a|cos θ * ( b / |b| ) )
2. 마우스를 따라 움직이는 몬스터 구현
(1) 내적 구현 (Types.h)
float Dot(Vector other)
{
return x * other.x + y * other.y;
}
벡터를 좌표로 나타내었을 때 a(x1, y1), b(x2, y2) 의 두 벡터를 내적한 결과는
x1*x2 + y1*y2 이다.
(2) 사양 변경
GameScene.cpp에서 몬스터가 마우스에 따라 움직이도록 변경할 것이므로, 플레이어 생성코드를 지우고, 몬스터를 1마리, 400, 400에 스폰하도록 변경한다.
void GameScene::Init()
{
// 몬스터 1마리 생성
{
//for (int32 i = 0; i < 5; i++)
{
Monster* monster = GET_SINGLE(ObjectManager)->CreateObject<Monster>();
monster->SetPos(Pos{ 400, 400});
GET_SINGLE(ObjectManager)->Add(monster);
}
}
}
Monster.h에 몬스터가 움직이는 시작과 끝 벡터를 지정한다.
private:
Vector _start = { 300, 100 };
Vector _end = { 600, 250 };
};
이어 Monster.cpp에서 몬스터가 움직이는 경로를 빨간색으로 그려보자.
void Monster::Render(HDC hdc)
{
Utils::DrawCircle(hdc, _pos, 50);
HPEN pen = ::CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
HPEN oldpen = (HPEN)::SelectObject(hdc, pen);
{
Utils::DrawLine(hdc, _start, _end);
}
::SelectObject(hdc, oldpen);
::DeleteObject(pen);
}
몬스터는 여기에서 그려진 빨간색 선을 따라 이동하게 될 것이다.
(3) 시작점에서 마우스까지의 벡터 구하기
(3-1) Types.h
헤더에 <windows.h>를 추가한다.
먼저 POINT 타입과 Vector 타입은 서로 호환이 되지 않기 때문에, 우리가 구현한 Vector 클래스의 생성자를 추가해준다.
struct Vector
{
Vector() {}
Vector(float x, float y) : x(x), y(y) { }
Vector(POINT pt) : x((float)pt.x), y((float)pt.y) { }
(3-2) Monster.cpp
헤더에 "InputManager.h"를 추가한다.
void Monster::Update()
{
Vector mousePos = GET_SINGLE(InputManager)->GetMousePos();
// 이동 경로의 벡터 계산
Vector v1 = _end - _start;
// 마우스에서 시작점 까지의 벡터
Vector v2 = mousePos - _start;
}
이제 v1 벡터에 정사영된 v2 벡터를 구할 것이다.
v1.Normalize();
float dot = v1.Dot(v2);
Pos pos = _start + v1 * dot;
_pos = pos;
}
v1를 단위벡터로 만들어주고 v2와 내적을 하면 v2의 정사영된 벡터 크기인 dot = |v2|cos θ를 구할 수 있다.
이제 시작 위치에 v1 단위 벡터와 정사영 벡터 크기를 곱한 값을 더해주면 된다.
만약 이 선을 벗어나지 못하게 하려면 아래와 같이 코드를 수정하면 된다.
float maxLength = v1.Length();
v1.Normalize();
float dot = v1.Dot(v2);
Pos pos = _start + v1 * dot;
if (dot < 0 || dot > maxLength)
return;
_pos = pos;
}
마우스와 시작점 사이의 각이 직각을 넘어 둔각이 되거나, 선의 길이를 벗어나지 못하게 구현한 코드이다.
'Windows API & 게임 수학' 카테고리의 다른 글
2-5. 삼각함수의 역함수 활용 - 각도 구하기, 백스텝 (0) | 2023.10.30 |
---|---|
2-4. 벡터의 외적을 활용하기 - 범위, 쿨타임 표시 (0) | 2023.10.30 |
2-2. 벡터를 이용한 기능 개선 - 유도탄 (0) | 2023.10.26 |
2-1. 삼각함수를 이용하여 여러 각도로 발사하기 (1) | 2023.10.26 |
1-11. 번외 - 충돌 판정(Collision) 구현하기 (0) | 2023.10.24 |