벡터의 내적과 외적 -내적

김재섭·2024년 10월 16일
0

외적,내적,,워낙 많이 들어본 두 이름이다.
두가지가 어떤 경우에 어떻게 쓰인다~ 까지는 암기하듯 외우고 있었다.
이번에 내적과 외적에 대해 찝찝하고 궁금했던것들을 제대로 공부해보았다.
혹시모를 나같은 완전 수포자분들에게 도움이될까 부족하지만 적어본다...

내적과 외적에 대해 적기 전에,

벡터(Vector)

벡터란 단순히 이야기하면 숫자를 원소로 가지는 배열이다.
이것을 사용해 하나의 숫자로는 표현이 어려운 것 들을 표현할 수 있다.

크기,방향,회전,힘,속도 등 다양한 양 을 표현할 수 있다.
게임 프로그래밍에서는 Position,Rotation,Scale도 Vector로 표현한다.

예시)
2D의 경우 A.position = new Vector2(1,0);
3D의 경우 B.position = new Vector3(1,0,3);

2D게임에서 Player의 position이 (2,3) , Enemy1의 position이 (4,1) 이라고 할때
그래프에 아래처럼 위치할 수 있다.

그래프에서의 내적

그래프, 게임응용에 가기 전에 단순히 공식으로만 먼저 봐보자.
단순히 내적을 구하는 "공식"은 (x의곱)+(y의곱) 이다.
그렇다면 위의 Player와 Enemy1의 경우에는 (2x4)+(3X1) 이니까 내적값은 11이 된다.

그래프로 그려본다면 이렇다.

여기서 Player와 Enemy1의 벡터값을 (0,0)으로부터 이은 선이 만나는 각도가 보인다.
한번 다른 점도 찍어볼까?

마찬가지로 여러개의 Enemy를 배치해 보았다.
Player(2,3)을 기준으로 위의 공식으로 내적값을 구했을때,

Enemy1(4,1)의 내적값은 11(양수)이고 예각을 나타낸다.
Enemy2(3,-2)의 내적값은 0이고 직각을 나타낸다.
Enemy3(-4,-1)의 내적값은 -11이고 둔각을 나타낸다.

아~ 내적값이 양수면 예각, 0이면 직각, 음수면 둔각이 되는구나~

...라고 이해 해 볼 수 있다.

방향벡터

방향 벡터란 쉽게말해서 객체가 바라보고 있는 방향을 나타내는 벡터다.
플레이어가 (5,7)방향으로 바라보고 있다면, 방향벡터는 (5,7)이다.

하지만 이 방향벡터는 단순히 방향만 나타내고있지 않다.
(5,7)은 방향뿐 아니라 크기를 나타내기도 한다. 이게 무슨뜻이나면


(5,7)과 (5.81,8.14)와 (6.98,9.77)은 크기가 다르지만 (0,0)을 기준으로 같은 방향으로 뻗어나가고있는 벡터다.

계산할때의 편의성과 일관성, 물리적 의미를 위해서 방향만을 표현하는 벡터를 구하고싶다.
순수한 방향만을 나타내는 방향벡터는 어떻게 구할 수 있을까?

이 때 정규화 라는걸 해주면 딱 방향만 나타내는 벡터를 구할 수 있다.
정규화란 한 벡터의 방향은 유지하지만 크기는 1이 되도록 다시 계산하는 것이다.
(값이-1 ~ 1이다.)

(5,7)과 (5.81,8.14)와 (6.98,9.77)은 정규화 하면 (0.58, 0.81)이 된다.
이 값은 유니티에서 Nomalize함수를 사용해 쉽게 얻을 수 있다.

정규화된 값(방향)에 힘을 구하면 객체의 속도를 구할 수 있다.

게임에서의 내적

이제 드디어 게임에서의 내적을 알아보기위한 재료가 다 모였다.

게임에서 벡터의 내적은 바라보는 방향을 구하는데에 응용된다.
Enemy가 Player를 바라보고있는지, 다른곳을 보고있는지 벡터의 내적을 사용해 구할 수 있다.

  1. Player와 Enemy1의 위치 벡터를 구한다.
Vector3 playerPosition = player.transform.position;
Vector3 enemy1Position = enemy1.transform.position;
  1. Player와 Enemy1사이의 방향 벡터(위에서 말한 정규화 된 값)을 구한다.
Vector3 direction = (playerPosition - enemy1Position).normalized;
  1. Enemy1이 바라보고있는 방향의 방향벡터를 구한다.
Vector3 enemyForward = enemy.transform.forward;
  1. 유니티의 Dot함수를 사용해 내적 계산을 해보자.
float dotProduct = Vector3.Dot(enemyForward, direction);
if (dotProduct > 0)
{
    // 내적값이 양수다.
}
else if (dotProduct < 0)
{
   // 내적값이 음수다.
}
else 
{
   // 내적값이 0이다.
}

지금은 검은선(player와enemy1의 방향벡터) 과
빨간선(enemy1이 바라보는방향) 이 예각을 띄고있다.

아까 빨간옷 입은 친구가 한 말을기억해보자.

내적값이 양수면 예각, 0이면 직각, 음수면 둔각

Enemy1의 시선의 방향벡터가 빨간 선이라면 플레이어 쪽을 바라보고있는것이다.
=> 두 벡터의 내적값이 양수일 때 플레이어쪽을 바라보고있는것이다.

Enemy1의 시선의 방향벡터가 파란 선이라면 플레이어와 수직의 방향을 바라보고있다.
=> 두 벡터의 내적값이 0일 때 플레이어와 수직의 방향을 보고있다.

Enemy1의 시선의 방향벡터가 초록 선이라면 플레이어 쪽을 바라보고있지 않은것이다.
=> 두 벡터의 내적값이 음수일 때 플레이어쪽을 바라보고있지 않은것이다.

이렇게 벡터의 내적값을 사용해서 객체 다른 객체를 바라보는지, 아닌지를 구할 수 있게 됐다.


면접관 : 벡터의 내적을 게임에 어떻게 적용할 수 있나요?

이제 두려워 하지 마세요!


이번 공부는 아래의 블로그에서 많은 도움을 받았다. 감사합니다!
https://gpfatp.blogspot.com/2019/08/1.html#

profile
Unity C#

0개의 댓글