[C++] 3.2.1 두 공의 충돌 : 벡터 개념

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모 교수님의 홍정모의 게임 만들기 연습 문제 패키지 강의를 듣고 정리한 필기입니다.😀
🌜 공부에 사용된 홍정모 교수님의 코드들 보러가기
🌜 [홍정모의 게임 만들기 연습 문제 패키지] 강의 들으러 가기!


Chapter 3. 게임 물리 맛보기 : 공 두 개를 충돌시켜보자

벡터, 상대 속도 등등, 해당 강의에서 다루었던 물리학적 개념들이 문과생인 나에겐 생소하고 잘 와닿지 않았던 개념이라 강의를 필기하기에 앞서 개인적으로 따로 공부하여 정리해보았다.

벡터 개념

C# 프로그래밍 : 벡터, 평행 이동 포스트도 참고!

🔔 벡터

image

스칼라와 벡터

  • 스칼라 : 크기
    • ex) 시간, 몸무게, 키 등등
  • 벡터 : 크기 + 방향
    • ex) 속도, 힘 등등

벡터의 크기와 방향

  • 벡터의 크기는 스칼라 값으로 피타고라스의 법칙으로 구할 수 있다.
    • 벡터의 크기 = 벡터의 길이 = 벡터의 절대값 = 화살표의 길이
    • 예시
      • 축구공이 멀리 날아갈수록, 즉 축구공이 날아간 행적을 표시하는 화살표의 길이가 길 수록 크기가 큰 벡터라고 말할 수 있다.
      • 165cm 라는 내 키도 땅을 시작점으로 해서 내 정수리의 끝점을 방향으로 하는 벡터의 크기라고 해석할 수 있음
  • 뱡향화살표로 표시한다.
    • 시작좌표 A, 종점 좌표 B라면 \(\vec{AB}\) 라고 표시할 수 있다.

같은 벡터

image

  • 시작점, 종점과는 상관 없이 벡터의 길이와 방향이 모두 같으면 같은 벡터다.
  • 벡터에게 위치는 중요하지 않다.
    • 같은 벡터라도 시작 좌표, 종점 좌표는 다를 수 있다.
      • 크기와 방향만 같다면 이리저리 옮겨다녀도 모두 같은 벡터.
    • 벡터는 어떤 특정 지점에 고정되어있지 않다.

프로그래밍에서의 벡터

image

  • 벡터는 <기하학>에서의 개념이지만 <대수학>영역인 프로그래밍에서 어떻게 쓰이는지를 잘 파악해야 한다.
  • Vector2(x, y), Vector3(x, y, z) 으로 나타낼 수 있다.
  • x, y, z 는 각각 벡터의 성분이 된다.
  1. 위치 좌표로 쓰임 (절대좌표)
    • 사실 위치 좌표는 스칼라로 보이더라도 이 또한 원점을 시작점으로, 해당 위치를 종점으로 하여 화살표로 이어진 벡터라고 해석할 수 있다.
    • 위치 좌표로서의 Vector2(2, 4)는 Vector2(0, 0) 원점을 시작점으로 했을 때 Vector2(2, 4)로 향하는 벡터라고도 할 수 있다.
  2. 벡터로 쓰임 (상대좌표)
    • 어떤 방향으로 얼마만큼의 크기 만큼 변화했는지의 정도

평행한 벡터

  • 방향이 같다는 의미.
    • \(\vec{a}\) 벡터와 \(\vec{b}\) 가 방향이 같을 경우 다음과 같이 표현할 수 있다.
    • \[\vec{b} = k \vec{a}\]
    • 방향과 더불어 크기까지 같을 경우 같은 벡터다. (\(k = 1\))
      • \[\vec{b} = \vec{a}\]
    • Vector2(2, 2)와 Vector2(3, 3)은 크기는 다르지만 방향은 같은 평행한 벡터다.


🔔 단위 벡터 ( = 방향 벡터)

image

어떤 벡터의 단위벡터란 그 벡터와 방향은 같되 크기는 1인 벡터이다. 오직 해당 벡터의 방향만을 나타냄.

  • cm 기준으로 단위는 1cm가 된다. 10cm는 10 * 1cm. 단위가 만약 1cm가 아니라 6cm, 0.2cm 이랬으면 계산하기가 복잡했을 것이다.
    • 이처럼 벡터를 단위벡터 * 크기 로 쉽게 표현할 수 있다.
      • 단위 벡터는 크기가 1이라 딱 방향만 나타내기 때문에 가능한 일.
  • 같은 크기(= 1) 라고 가정하면 비교하기가 편함
    • 크기는 무시하고 두 벡터의 방향만을 비교하고 싶다면 두 벡터의 단위 벡터를 비교하면 됨.
  • 단위 벡터끼리 곱하는 연산은 천만번 곱해도 단위벡터다.
    • 이 사실만으로 연산을 아주 간소화 할 수 있다.

단위 벡터의 표현

  • 벡터 i는 수평 방향을 향하는 크기 1의 단위 벡터
\[\hat{i} = {1\brack0}, \vert{\hat{i}}\vert=1\]
  • 벡터 j는 수직 방향을 향하는 크기 1의 단위 벡터

    \[\hat{j} = {0\brack1}, \vert{\hat{j}}\vert=1\]
  • 벡터 v는 i 를 2배 크기로 늘린 벡터와 j 를 3 배 크기로 늘린 벡터의 덧셈과 같다.

    \[\vec{v} = 2\hat{i}+3\hat{j}\]
  • 이처럼 단위 벡터 i,j 로 모든 벡터를 표현할 수 있다.

단위 벡터 구하기

방향벡터 포스트 참고

단위 벡터 = 벡터의 성분 / 벡터의 길이

\[Vector2(x,y)'s 단위벡터 = ({x\over \sqrt{x^2 + y^2}} , {y\over \sqrt{x^2 + y^2}})\]

\[\vec{A} ‘s 단위벡터 = {\vec{A}\over{\vert\vec{A}\vert}}\]


🔔 벡터의 덧셈

image

  • 성분끼리 더해주면 땡이다.
  • 이동량을 더해줄 때 많이 사용!
    • 좌표 이동시킬 때 등등
  • 바람의 힘 벡터를 만나 자동차의 운동 벡터는 방향과 힘이 저렇게 바뀐다!
    • 변경된 자동차의 벡터 = 자동차의 원래 벡터 + 바람 벡터
    • 바람 벡터만큼 더해주는 셈

벡터의 덧셈 원리

  • image
  1. 두 벡터를 이어지도록 시작점을 합친다.
    • image
  2. 시점을 합친 상태에서 \(\vec{A}\)벡터의 시작점에서 \(\vec{B}\)벡터의 종점으로 이어 새로운 벡터를 만든다.
    • image

image


🔔 벡터의 뺄셈

영벡터와 역벡터

  • 영벡터
    • 크기가 0 인 벡터.
    • 고로 방향도 없다.
  • 역벡터
    • 크기는 같고 방향만 정반대인 벡터
    • 시작점과 종점이 서로 바뀜.
    • \(\vec{A}\)벡터의 역벡터는 \(-\vec{A}\)벡터이며
    • \(\vec{A} + (-\vec{A}) = 영벡터\)

image

벡터 뺄셈의 원리

image

  • \(\vec{A} -\vec{B} = \vec{A} + (-\vec{B})\)
    • \(\vec{A}\)벡터와 \(\vec{B}\)벡터의 뺄셈은
    • \(\vec{A}\)벡터와 \(\vec{B}\)벡터의 역벡터인 \((-\vec{B})\)벡터와의 덧셈과 같다.

벡터의 뺄셈 = 종점벡터 - 시작벡터

  • 벡터의 뺄셈으로 기준이 되는 위치벡터에서 얼만큼 이동해야 목적지 벡터에 도달할 수 있는지 알 수 있다. ⭐⭐⭐

플레이어를 따라가는 AI 몬스터

image

  • 몬스터는 계속 플레이어를 따라가야 한다.
    • 플레이어의 위치 (목적지 벡터)로부터 몬스터의 위치(출발지 벡터)를 뺀 거리벡터
      • player.transform.position - transform.position (몬스터 입장에서)
      • 👉 몬스터가 플레이어 위치에 도달하기 까지 움직여야할 길이와 방향을 뜻함
      • 이 거리 벡터의 단위 벡터를 구하면 그게 바로 몬스터(시점)가 플레이어(종점)를 바라보는 방향이 된다.
        • 몬스터가 플레이어를 바라보는 방향 = (플레이어벡터 - 몬스터벡터)의 단위벡터
  • 플레이어를 향해 몬스터를 움직이게 하려면 플레이어의 위치벡터로부터 몬스터의 위치벡터를 뺄셈한 결과값을 몬스터의 위치에 매 프레임마다 더해주면 된다.
    • 몬스터 위치 += 플레이어 위치벡터 - 몬스터 위치벡터

두 벡터의 뺄셈의 단위 벡터 = 몬스터(시점)가 플레이어(종점)을 바라보는 방향

  • 단위벡터에 몬스터로부터 플레이어까지의 거리의 크기를 곱하면 몬스터 위치로부터 플레이어 위치에 도달하는 거리 벡터가 된다.
    • 몬스터에서 플레이어까지의 벡터의 크기가 N 이라면 이 단위벡터를 계속 ‘N’번 덧셈하면 몬스터가 플레이어에 다다를 수 있게 된다.

image

Vector3 velocity = (player.transform.position  transform.position).normalized;
velocity = velocity * 10.0f;
transform.position = transform.position + Time.deltaTime * velocity;
  • Vector3 velocity = (player.transform.position – transform.position).normalized;
    • 몬스터가 플레이어를 향하는 방향벡터
      • (플레이어의 위치 - 몬스터의 위치).normalized
      • normalized 하여 방향 벡터를 구함.
      • 크기는 1이고 오로지 몬스터가 플레이어를 바라보는 방향만을 나타낸다.
  • 🚗velocity = 🚕velocity * 10.0f;
    • 🚕velocity
      • 몬스터가 플레이어를 바라보는 방향벡터
    • 🚕velocity * 10.0f;
      • 크기를 10으로 곱함.
    • 🚗velocity
      • 최종 속도 벡터.
      • 몬스터가 플레이어를 바라보는 방향 + 크기는 10인 벡터.
      • 몬스터는 1 프레임당 10의 크키 단위로 플레이어를 향해 움직일 것.
      • 방향에 속력(크기)를 곱해 속도를 만듬.
        • 이 속력 값이 클 수록 더 빨리 움직이겠지.
  • transform.position = transform.position + Time.deltaTime * velocity;
    • 몬스터의 새로운 위치 = 몬스터의 기존 위치 + 시간 * 속도
      • 몬스터 기준에서 플레이어를 추적하는 방향으로 매 프레임마다 10.0f 크기의 벡터를 더한다.
      • 매 프레임마다 몬스터가 플레이어를 추적하게 될 것.


🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

C++ games 카테고리 내 다른 글 보러가기

댓글 남기기