컴퓨터 그래픽스 : 수학/게임 수학

[게임 프로그래머 입문 올인원] 게임수학 : 외적 (97강)

순정법사 2024.04.11

A. 외적

1. 외적의 기초 

a. 외적이란?

*가 아니라 외적을 한다는 의미

 

외적의 값은 벡터 (내적처럼 스칼라가 아님)

2D에서는 외적이라는 개념이 존재하지 않지만 사용함 (z축 값을 0이라고 전제) 

 

a와 b에 외적을 때리면 수직인 보라색 화살표로 올라감 = K / 오른쪽 그림과 같다 

 

내적은 반대로 해도 값이 그대로이지만 외적은 반대로 하게되면 (위에서는 bXa) 음수값이 나옴 

= 즉 시계방향/ 반시계 방향에 따라 k의 방향이 바뀌는게 핵심!

 

b. 외적 응용 예시

시계방향인지 반시계인지 외적을때려서 체크할 수 있게됨

 

두 개를 외적시키면 둘 다 같은 반시계 방향을 가리키지만, p가 외부에 있다면 다른 방향이 됨 = 범위에 벗어난걸 체크할 수 있음

 

즉, P가 A와 B에 들어와있는지 체크하기 위해 사용할 수 있음

 

점 하나를 더 추가해서 P가 삼각형 안에 있는지도 확인할 수 있음

 

 

2. 게임에 외적 더하기

a.Vector에 외적 추가하기

2D니까 일단 k를 한쪽방향으로 지정해줌 (반대는 음수로 나옴)

 

b. 몬스터 수정하기

 

Monster.cpp에서 몬스터 업데이트 하는 (내적) 코드는 날려주기 

 

위에서 생성한 선을 연결해 삼각형을 만들어주고(빨간색), 마우스 위치를 선으로 그려주는 코드를 작성

 

c. 마우스 포지션과 삼각형 외적하기

그럼 이렇게 나오는데, 여기서 마우스 위치가 삼각형 안에 있는지 외적을 3번 해서 값을 구할것임

 

외적하는 코드를 작성해줌

 

위 코드를 그림으로 그리면 이렇게 되고

 

실행해보면 마우스 위치에 따라서 양수값인지 음수값인지 알 수 있음

 

코드를 조금 더 다듬으면 아래와 같이 됨

 

◽◽◽ 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;
}

void Monster::Update()
{
	
}

void Monster::Render(HDC hdc)
{
	// 로밍 경로
	HPEN pen = ::CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	HPEN oldPen = (HPEN)::SelectObject(hdc, (HGDIOBJ)pen);
	//삼각형 빨간펜으로 그려주기
	{
		Utils::DrawLine(hdc, _pt1, _pt2);
		Utils::DrawLine(hdc, _pt2, _pt3);
		Utils::DrawLine(hdc, _pt3, _pt1);
	}
	::SelectObject(hdc, oldPen);
	::DeleteObject(pen);

	//////////////////////

	//마우스 위치 
	Vector mousePos = GET_SINGLE(InputManager)->GetMousePos();
	_pos = mousePos;

	{
		Utils::DrawTextW(hdc, _pt1, L"P1");
		Utils::DrawTextW(hdc, _pt2, L"P2");
		Utils::DrawTextW(hdc, _pt3, L"P3");
		Utils::DrawLine(hdc, _pt1, mousePos);
	}

	//벡터 3개를 만들어주고
	Vector v12 = _pt2 - _pt1;
	Vector v1m = mousePos - _pt1;
	Vector v13 = _pt3 - _pt1;

	//정규화 시켜주고
	v12.Normalize();
	v1m.Normalize();
	v13.Normalize();

	//순서대로 외적해주기
	float c1 = v12.Cross(v1m);
	float c2 = v1m.Cross(v13);

	if (c1 >= 0 && c2 >= 0)
	{
		_pos = mousePos;
	}
	else
	{
		_pos = { -1000, -1000 };
	}

	{
		POINT mousePos = GET_SINGLE(InputManager)->GetMousePos();
		wstring str = std::format(L"c1({0}) c2({1})", c1, c2);	//c1, c2 좌표 보기
		Utils::DrawTextW(hdc, { 20, 50 }, str);
	}
}

 

 

 


출처 :https://www.inflearn.com/course/%EA%B2%8C%EC%9E%84-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8-%EC%9E%85%EB%AC%B8-%EC%98%AC%EC%9D%B8%EC%9B%90-rookiss#curriculum

 

[게임 프로그래머 입문 올인원] C++ & 자료구조/알고리즘 & STL & 게임 수학 & Windows API & 게임 서버 -

어디부터 시작할지 막막한 게임 프로그래밍 입문자를 위한 All-In-One 커리큘럼입니다. C++, 자료구조/알고리즘, STL, 게임 수학, Windows API, 게임 서버 입문으로 이어지는 알찬 커리큘럼으로 게임 프

www.inflearn.com

https://ballpen.blog/%EC%99%B8%EC%A0%81-%EB%B2%A1%ED%84%B0%EB%81%BC%EB%A6%AC-%EA%B3%B1%ED%95%98%EC%97%AC-%EB%B2%A1%ED%84%B0%EA%B0%80-%EB%90%98%EB%8A%94-%EA%B3%84%EC%82%B0%EB%B2%95/

 

외적 - 벡터끼리 곱하여 벡터가 되는 계산법 - ilovemyage

외적(vector product)을 소개합니다. 외적한 결과는 벡터로서 나오기 때문에 '벡터곱'이라고도 합니다. 외적의 크기는 두 벡터가 만드는 평행사변형의 면적이 되고, 외적의 방향은 오른손 법칙을 적

ballpen.blog