A. 역삼각함수
1. 역삼각함수 기초
a. 함수와 역함수
역함수는 항상 존재하지 않고, 1:1 대응이여야지만 존재한다
b. 삼각함수와 역삼각함수
이렇게 동일한 값이 무한으로 나와서 역함수가 어렵지만
범위를 강제로 지정해서 사용할 수 있음
즉, cos의 val가 -1~1이라고 하면 각도는 0~180
동일하게 sin, tan의 val가 -1~1이라고 하면 각도는 -90~90
원하는 벨류를 넣어줘도 원하는 값이 튀어나온다는 보장이 없음
🌟 역삼각함수에서 튀어나온 각도의 범위는 0~180 / -90~90라는 점을 꼭 기억해야 함
2. 게임에 역삼각함수 더하기
백스텝 : 뒤에서 타격하면 가산점수처럼 각도계산을 해서 다른 점수를 줘야 할 때
a. 몬스터 방향 정보 추가하기
b. 몬스터 생성 및 방향 만들기
여기서 마우스 위치에 따라 몬스터를 공격하는 각도를 계산할 것임
기준은 마음대로 설정!!
c. 전략 세우기
여기에 아크코사인을 때려주면 각도가 나온다!!
d. 각도 구하기
e. 각도 보정하기
만약에 180도 이후의 각도를 얻고싶으면 외적하거나 왼쪽/오른쪽 처리로 보정할 수 있음 (다양한 방법)
1) 좌표를 통한 판별하기 - X
💥 몬스터가 다른쪽을 바라보고 있으면 좌표가 틀어져버림 (하드코딩으로 인한)
2) 내적을 이용한 우측 판별 방법
3) 외적을 이용한 우측 판별 방법 - O
시계방향, 반시계방향으로 판별하는 방법
f. 각도 출력하기
◽◽◽ Monster.cpp
#include "pch.h"
#include "Monster.h"
#include "InputManager.h"
Monster::Monster() : Object(ObjectType::Monster)
{
}
Monster::~Monster()
{
}
void Monster::Init()
{
_stat.hp = 100;
_stat.maxHp = 100;
_stat.speed = 10;
_pos = Pos{ 400, 300 }; //먼저 세팅해주고
_lookPos = Pos{ 530, 70 }; //다른 위치를 바라보게
_lookDir = _lookPos - _pos; //바라보는 위치 - 현재 위치
_lookDir.Normalize(); //단위 벡터로 관리
}
void Monster::Update()
{
}
void Monster::Render(HDC hdc)
{
// 몬스터 등장
Utils::DrawCircle(hdc, _pos, 100);
// Front Dir : 몬스터가 바라보는 방향
HPEN pen = ::CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
HPEN oldPen = (HPEN)::SelectObject(hdc, (HGDIOBJ)pen);
{
Utils::DrawLine(hdc, _pos, _lookPos);
}
::SelectObject(hdc, oldPen);
::DeleteObject(pen);
//////////////////////
Vector mousePos = GET_SINGLE(InputManager)->GetMousePos();
//몬스터 방향 v2
Vector dir = _lookDir;
dir.Normalize();
//마우스 - 몬스터방향 v1
Vector monsterToMouseDir = mousePos - _pos;
monsterToMouseDir.Normalize();
//float dot = dir.Dot(monsterToMouseDir);
float dot = monsterToMouseDir.Dot(dir); //두개 방향 내적하고
float rad = ::acos(dot); //아크코사인 하면 각도만 나옴
float angle = rad * 180 / 3.14; //각도로 변환해주기
// 0) 좌표를 통한 판별 방법
//if (monsterToMouseDir.x < 0)
// angle = 360 - angle;
// 1) 내적을 이용한 우측 판별 방법
/*Vector rightDir = {};
{
float rotateAngle = 3.14f / 2;
rightDir.x = _lookDir.x * cos(rotateAngle) - _lookDir.y * sin(rotateAngle);
rightDir.y = _lookDir.x * sin(rotateAngle) + _lookDir.y * cos(rotateAngle);
Utils::DrawLine(hdc, _pos, _pos + rightDir * 50);
float rightDot = rightDir.Dot(monsterToMouseDir);
if (rightDot < 0)
angle = 360 - angle;
}*/
// 2) 외적을 이용한 우측 판별 방법
float cross = _lookDir.Cross(monsterToMouseDir);
if (cross < 0)
angle = 360 - angle;
{
//마우스 좌표 찍기
Utils::DrawLine(hdc, _pos, mousePos);
}
{
//각도 찍어주기
wstring str = std::format(L"angle({0})", angle);
Utils::DrawTextW(hdc, { 20, 50 }, str);
}
}
'컴퓨터 그래픽스 : 수학 > 게임 수학' 카테고리의 다른 글
[게임 프로그래머 입문 올인원] 게임수학 : 포트리스 모작 #2 (100강) (1) | 2024.04.16 |
---|---|
[게임 프로그래머 입문 올인원] 게임수학 : 포트리스 모작 #1 (99강) (0) | 2024.04.15 |
[게임 프로그래머 입문 올인원] 게임수학 : 외적 (97강) (0) | 2024.04.11 |
[게임 프로그래머 입문 올인원] 게임수학 : 내적 (96강) (0) | 2024.04.11 |
[게임 프로그래머 입문 올인원] 게임수학 : 벡터 (95강) (0) | 2024.04.11 |