티스토리 뷰

Book

VECTORS AND BASIC PHYSICS

BaeMinCheon 2018. 7. 4. 18:39

VECTORS AND BASIC PHYSICS

본 포스팅은 Sanjay Madhav 가 집필한 Game Programming in C++ (2018) 의 내용을 정리한 글입니다
그 중에서도 3장 VECTORS AND BASIC PHYSICS 의 내용을 다룹니다


Overview

본 장에서는 아래와 같은 내용을 배울 수 있습니다

  • Vectors
    • 벡터로 문제를 해결하는 여러 가지 방법들
  • Basic Movement
    • MoveComponent 클래스로 움직임을 구현하는 방법
    • InputComponent 클래스로 키보드 조작을 구현하는 방법
  • Newtonian Physics
    • 아주 약간의 뉴턴 물리학
  • Basic Collision Detection
    • 물체간의 충돌을 감지하는 방법

Vectors

벡터 연산의 경우 책의 수식이 보기 힘들어 별도의 자료를 찾아보는 것을 추천합니다
따라서 벡터 연산에 사용되는 용어를 정리해두기만 하겠습니다

  • Vector Operation
    • magnitude
      • 벡터 크기
    • length
      • 벡터 길이 ( 벡터 크기의 또 다른 표현 )
    • length squared
      • 벡터 길이의 제곱값 ( 연산량을 줄이기 위해 도입한 개념 )
    • unit vector
      • 단위 벡터
    • Dot Product
      • 내적 ( Inner Product 의 또 다른 표현 )
    • Cross Product
      • 외적 ( Outer Product 의 또 다른 표현 )
  • Applying Vector Operation to Game
    • 두 점 사이의 거리 구하기
      • 각 점을 가리키는 벡터로 \vec{V_1}, \vec{V_2} 를 가진다고 할 때
      • \vec{V_1} = (a, b), \vec{V_2} = (c, d) 에서 두 벡터의 뺄셈 \vec{V_3} = (a - b, c - d)
      • 두 점 사이의 거리 |\vec{V_3}| = \sqrt{(a - b)^2 + (c - d)^2}
        ※ 게임상에서 두 물체간의 거리를 계산할 때 사용
    • 두 벡터 사이의 각도 구하기
      • 임의의 두 벡터 \vec{V_1}, \vec{V_2} 가 존재한다고 할 때
      • 두 벡터의 내적 \vec{V_1} \cdot \vec{V_2} = |\vec{V_1}||\vec{V_2}|cos(\theta) 에서
      • 두 벡터 사이의 각도 \theta = arccos(\dfrac{\vec{V_1} \cdot \vec{V_2}}{|\vec{V_1}||\vec{V_2}|})
        ※ 이렇게 구한 각도를 단위 벡터로 변환해 물체의 방향을 계산
        ※ 물체의 방향을 가리키는 단위 벡터 \vec{u} = (cos(\theta), ±sin(\theta))
        ※ sin(\theta) 의 부호는 시스템의 좌표계에 따라 덧셈인지 뺄셈인지 결정

Basic Movement

게임 상에서 움직여야하는 물체들은 MoveComponent 를 가지게 한다
그리고 MoveComponent 에서 움직이는 규칙을 명시하도록 한다

  • Transformation
    • deltaTime 에 대해 종속적
    • 현재 위치에 진행 속도 * deltaTime 의 값을 더한다
    • 진행 속도는 방향 벡터 * 진행 속력 의 값으로 구해진다
  • Rotation
    • deltaTime 에 대해 종속적
    • 현재 각도에 회전 속도 * deltaTime 의 값을 더한다
    • 회전 속도는 회전 속력 의 값으로 구해진다
      ※ 음수 또는 양수만으로 두 방향에 대한 회전을 표현할 수 있기 때문
  • Keyboard Input
    • 조작가능한 물체일 경우 키보드 입력에 따라 이동 및 회전이 가능해야 한다
      • 따라서 조작가능한 물체의 클래스는 InputComponent 를 포함시킨다
    • 특정 키보드 입력값에 따라 진행 속력 또는 회전 속도 를 결정한다

Newtonian Physics

현실에는 뉴턴 물리학으로 설명할 수 없는 문제들이 많지만 게임은 뉴턴 물리학으로도 충분히 구현 가능하다
따라서 우리는 뉴턴 물리학을 기반으로 각 물체들의 운동을 구현한다

  • Newton's second law F = m \cdot a
    • 어떤 물체에 가해지는 힘의 총합은 물체의 질량과 가속도의 곱과 같다
    • 여기에서 속도 v 는 가속도와 시간의 곱과 같다 v = a \cdot t
    • 그리고 이동거리 p 는 속도와 시간의 곱과 같다 p = v \cdot t
    • 따라서 F = m \cdot a = m \cdot v / t = m \cdot p / t^2 이고 p = \dfrac{F \cdot t^2}{m}
  • Applying to MoveComponent::Update(float)
    • deltaTime 에 대해 종속적
    • 매 프레임마다 위의 방식을 활용해 이동거리를 계산하고 그 결과값만큼 이동한다
      • 물체에 가해지는 힘을 중첩시키기 위해 AddForce() 사용

Basic Collision Detection

연산량과 타협하기 위해 물체들의 윤곽을 원형으로 생각하고 충돌을 검출한다
즉 물체간 충돌 검출 문제를 원형간 충돌 검출 문제로 축약한다

  • Circle VS. Circle
    • 두 원형이 서로 겹쳐있는지 검사하는 것으로 충돌을 검출한다
      • 두 원형이 겹쳐있다는 두 원형의 반지름 합이 두 원형의 중심간 거리보다 클 때 참이다
    • 각 원형의 반지름을 R_1, R_2 라 하고 중심간 거리를 D 라 할 때 D - ( R_1 + R_2 ) 의 값을 검사한다

      • D - ( R_1 + R_2 ) > 0
        두 원형이 서로 접촉하지 않았음을 의미
      • D - ( R_1 + R_2 ) = 0
        두 원형이 한 점에서 접촉하는 것을 의미 → 충돌
      • D - ( R_1 + R_2 ) < 0
        두 원형이 한 면에서 접촉하는 것을 의미 → 충돌
  • Applying to Intersect()
    • 두 점 사이의 거리를 구하기 위해 두 물체의 중심을 가리키는 벡터간 뺄셈을 수행한다
    • 뺄셈으로 인해 생성된 벡터의 길이를 구해 두 점 사이의 거리를 구한다
      • 연산량을 줄이기 위해 length squared 에 해당하는 LengthSq() 를 사용

Exercise

예제 풀이는 https://github.com/BaeMinCheon/game-programming-in-cpp 의 commits 참고

'Book' 카테고리의 다른 글

OPENGL  (0) 2018.07.06
ARTIFICIAL INTELLIGENCE  (0) 2018.07.04
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함