노력과 삽질 퇴적물

게임 수학&물리 (1) 본문

📂게임개발 note/미분류

게임 수학&물리 (1)

MTG 2016. 4. 29. 23:37

해당 포스팅은 '까먹은거 다시 하기'가 목적이며 아래의 목차내에서만 다루겠습니다.

포스팅상 다루지 못하는 파트의 경우,

구현상 필요할때마다 찾아서 쓰는게 효율적이라 생각되어 생략했습니다.


수학

물리

1. 방정식: 1, 2, 3차

2. 직선

3. 원&구

4. 선형대수

  > 행렬&행렬식&역행렬

  > 벡터

5. 미적분

  > 삼각함수 미분

  > 적분, 적분을 이용한 넓이와 부피

1. 속도와 가속도

2. 운동의 법칙

3. 운동량과 충격량

4. 일과 에너지


* 포물선은 내용상 물리에서 종합적으로 정리






1. 방정식


1) 1차 방정식

Ax+B=0  [A!=0]

> 직선

> (A/B)x=0으로 기울기 구하는데 쓰임. [이하, 기울기 M]

> 두 직선이 직교(수직으로 겹치는거)할 경우, 두 직선의 M을 곱했을때 -1

  예. (B/A) * (-A/B) = -1




2) 2차 방정식

Ax^2+Bx+C=0  [A!=0]


① 근의 공식 만들기






상수를 우변으로 넘긴후,

좌변에서 2차의 상수를 없애고,

좌변을 완전제곱으로 만듭니다.


제곱을 ^(1/2)시켰기 때문에 우변에 ±가 붙습니다.


짝수 공식의 경우, [B=2k]등으로 대입시키면 공식의 표현이 좀더 간결해집니다.














② 근을 이용한 계수의 관계

x의 근이 α와 β로 정의시,


2차 함수 그래프

  예: (X+1)(X-2)


 Ax^2+Bx+C는 포물선형 그래프가 된다.

> A>0, 포물선이 아래로 막힘.(=최소값 존재)

> A<0, 포물선이 위로 막힘.(=최대값 존재)

-> 연상법. 바닥이 둥근 컵에 물을 채우는데,

   물을 담으면(+) 컵을 세운거고, 물을 쏟으면(-) 컵을 엎은것.


 근의 갯수만큼 X축과 겹친다.

> 2개: (x+α)(x+β)

        B^2 - 4AC > 0

> 1개: Ax(x+α)

        B^2 - 4AC = 0

> 0개: Ax^2+C

        B^2 - 4AC < 0



* 그래프 툴 #PAGE

 



3) 3차 방정식

Ax^3+Bx^2+Cx+D=0  [A!=0]


① 3차 함수 그래프

 X축과 접하는 갯수 == 근의 갯수

 



4) 활용, 충돌체크

-> 두 직선이 만나는가?

    Ax+B=0, A'x+B'=0

    Ax+B = A'x+B'

    (A-A')x = B'-B 






2. 직선


1) 점과 직선

① 두 점 사이의 거리

-> A(x1, y1), B(x2, y2)

    { (x1-x2)^2+(y1-y2)^2 }^(1/2)

1
2
3
4
5
6
7
8
import math;
 
def PrintDistance(pt_a, pt_b):
    result = math.sqrt( math.pow(pt_a[0]-pt_b[0], 2+ math.pow(pt_a[1]-pt_b[1], 2) );
    print result;
    pass;
 
PrintDistance([20,16], [49]);
cs


② 두 직선 관계성

 

평행

일치

수직

표준형

  y = mx + a  // m이 기울기

  y = m'x + b // m'이 기울기

m = m'

 b

m = m'

a = b

m * m' = -1

일반형

  ax+by+c=0

  a'x+b'y+d=0

a/a' = b/b' ≠ c/c'

a/a' = b/b' = c/c'

a*a' + b*b' = 0

연립 방정식 근의 갯수

X

 ∞

1

> 수직이 되는 두 직선의 유형중, 접선과 법선도 있다.


2) 점과 직선 사이의 거리

-> [#참조]   [#증명]

-> 점과 평면의 경우, 해당 공식을 3차원으로 늘려서 사용하면 가능.

P(x1, y1)

직선 ax2+by2+c = 0

① 수선(점과 직선이 수직으로 만나는) 방정식

-> y - y1 = (x-x1) * {(y2-y1)/(x2-x1)}

② 직선과 교점의 좌표

③ A와 B의 거리


1
2
3
4
5
6
7
8
9
10
11
12
13
def PointToLine(pt_a, line):
    result = pt_a[0]*line[0+ pt_a[1]*line[1+ line[2];# aX+bY+c
    
    if result < 0:
        result *= -1;
        pass;
    
    result /= math.sqrt( math.pow(pt_a[0], 2+ math.pow(pt_a[1], 2) );
    
    print result ;
    pass;
 
PointToLine([0-1], [3-21]);#example
cs






3. 원&구


1) 원의 방정식

-> (평면기준) 중심점(a, b)에서 일정한 거리(반지름r)에 있는 점들의 연속.

① 표준형: (x-a)^2+(y-b)^2 = r^2

② 일반형: x^2+y^2+Ax+By+C = 0



2) 거리관계

① 두원의 위치관계

 * 두 원의 반지름은 각각 r, r' [단, r>r'] / 원의 중심점사이의 거리=d

d > r+r'   두 원은 접점이 전혀 없다. (충돌X)

d = r+r'   (접점이 1개인) 외접.

r-r < d < r+r'   두 원의 접점이 2개.

d = r-r'    (접점이 1개인) 내접.   //작은 원이 큰원 속에 포함.

d < r-r'   //작은원이 큰원 내부

② 공통 접선의 거리

 * 원의 중심점사이의 거리=d

공통외접선 l: (d^2 - (r-r')^2)^(1/2)

공통내접선 l: (d^2 - (r+r')^2)^(1/2)

③ 원과 접선

 * 원밖의 점(a,b)

접선의 방정식

  y-b = m(x-a)


*활용

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
32
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import math;
 
def GetCollision(circle1, circle2):
    distance = math.sqrt( math.pow(circle1[0]-circle2[0], 2+ math.pow(circle1[1]-circle2[1], 2) );
 
    if circle1[2]<circle2[2]:#반지름 길이에 따른 추가처리
        tmp = circle2[2];
        circle2[2= circle1[2];
        circle1[2= tmp;
        pass;
 
    if distance <= (circle1[2- circle2[2]):
        print "It's a bullet hole. remove bullet";
        pass;
    elif distance > (circle1[2+ circle2[2]):
        print "NOT Collision";
        pass;
    elif distance==(circle1[2+ circle2[2]):
        print "light scratch";
        pass;
    elif distance < (circle1[2+ circle2[2]):
        print "deep scratch";
        pass;
    pass;#    END. GetCollision
 
GetCollision([002], [3-42]);#NOT Collision
GetCollision([002], [3-43]);#light scratch
GetCollision([002], [3-44]);#deep scratch
GetCollision([002], [3-410]);#It's a bullet hole. remove bullet
cs



3) 구의 방정식

① 표준형: (x-a)^2+(y-b)^2+(z-c)^2 = r^2

② 일반형: x^2+y^2+z^2 = r^2







1) 행렬

-> [#위키백과, 행렬]

① 행렬의 합/차

 합하려는 행렬들의 규격이 일치해야 한다.

 계산하려는 행렬의 순서를 바꿔도 계산에 지장X

 ② 행렬의 곱

 곱하려는 행렬들의 규격이 호환되어야 한다.(?)

-> 2*4행렬과 4*3행렬 [O]

    2*4행렬과 3*4행렬 [X]

 계산하려는 행렬의 순서를 바꿔도 계산에 지장O

 [#슈트라센 알고리즘, Strassen algorithm]

 ③ 항등행렬

 I로 표기되곤 한다.

 왼쪽 위->오른쪽 아래방향 대각선의 행렬원이 1이고 나머지가 0인 행렬.

 ④ 전치행렬[A^t]

 [#참조]
예. 4x2행렬 --(행렬의 전치)-->2x4행렬

-> (연상법)손바닥을 가로방향&엄지가y+방향일때 손바닥을 뒤집어 손등이 보이고 엄지가 x+방향이 되는 회전.



2) 행렬식

① 행렬식의 성질

* 한 행에만 N배를 하면, 행렬식의 값도 N가 된다.  [단, N차 정방행렬]

* 두행의 원소가 비례관계이면 행렬식은 0

* 특정행을 N배해서 다른행에 더해도 행렬식값이 변하지 않는다.

* |A| = |A 전치행렬|

* |A*B| = |B|*|A|


② 계산

-> '행렬을 인수분해' / '일반화된 N차 정방행렬'이 라는 표기로도 있다.

 * 2차원 행렬

 A = [[a, b],

        [c, d]] 일때, 

 │A│ = Det(A) = ad-bc

 * 3차원(이상) 행렬

-> laplace전개 활용

 A = [[a, b, c],

        [d, e, f],

        [g, h, i]] 일때, 2가지 방법으로 구할수 있으나 공식으로는 동일하다.

 Det(A) = a(ei-fh) - b(di-fg) + c(dh-eg)

-> [#참조링크]



3) 행렬 연산

-> [#참조, 가우스 소거법]

-> 행렬식 값이 0이면 역행렬은 존재X

->  [#참조, 역행렬의 성질]


① 2차원 행렬, 역행렬

-> 역대각선(우측상단에서 좌측하단)기준으로 뒤집고, 대각선 행렬원소는 *=-1

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import math;
 
def InverseMatrix_2D(matrix):
    tmp = 1.0/(matrix[0][0]*matrix[1][1- matrix[0][1]*matrix[1][0]);
    print tmp;#(1/행렬식의 값)
    if tmp==0:
        print "Inverse matrix isn't exist."
        return;
        pass;
 
    tmp2 = matrix[0][0];
    matrix[0][0= matrix[1][1];
    matrix[1][1= tmp2;
    matrix[0][1*= -1;
    matrix[1][0*= -1;
 
    for row in range(02):
        for col in range(02):
            matrix[row][col] *= tmp;
            pass;
        pass;
    
    print matrix;
    pass;
 
matrix = [[3040], [-20-10]];
InverseMatrix_2D(matrix);
cs


② 3차원 행렬, 역행렬

-> 1/│A│ * adj(A)

-> [#계산법]

-> [#참조 링크]


행렬의 계수

* 성질

-> 전치행렬화 해도 계수는 동일

-> 두행을 바꾸어도 동일한 계수

-> 특정행만 N배해도 계수는 동일 [단, N은 0이 아님]

-> 특정행을 N배해서 다른행에 더해도 계수는 동일

-> 0으로만 구성된 행은 추가/제거해도 계수는 동일


④ 1차 연립방정식과 계수

-> 행렬A와 B의 계수값에 따라 연립방정식 근의 갯수가 달라진다.



5) 벡터

① 벡터의 성질

-> [#참조링크]


② 연산

 합

 →     →     →

 AB + BC = AC

* 3단 논법과 같은 흐름.

  A에서 B로 이동, B에서 C로 이동.

  결론. A에서 C로 이동했다.

 차

 →    →     →

 AC - AB = BC

 →      →      →

 AC +(-AB) = BC  //벡터는 방향과 크기를 나타내는거라서


 →     →     →

 AC + BA = BC  //벡터의 성질상 합&차는 순서를 바꿔도 계산에 지장X 


③ 벡터의 성분

 평면벡터

 →              →

 a = (a1, a2), b = (b1, b2)

 →

 AB = (b1-a1, b2-a2)  //성분

  →

 |AB| = {(b1-a1)^2 + (b2-a2)^2}^(1/2)  //크기

 공간벡터

 →

 a = (a1, a2, a3)

 →

 |a| = {a1^2 + a2^2 + a3^2}^(1/2)

 방향코사인 [#참조링크]


④ 벡터의 내적

> 두 벡터의 내적은 스칼라다. (=크기값만 있다.)

 평면벡터의 내적

 →   →
 a  ·  b  = |a||b| * cosΘ   //여기서 cos각은 

 성분표시

 →              →

 a = (a1, a2), b = (b1, b2) 일때

 →   →
 a  ·  b  = (a1 * b1) + (a2 * b2)

 내적의 성질 교환법칙 가능
 분배법칙 가능
 결합법칙 가능
 벡터의 수직
 (영벡터가 아닌 두 벡터)
 →   →   →   →
 a ⊥ b,   a  ·  b = 0   // cos 90° == 0
 벡터의 평행
 (영벡터가 아닌 두 벡터)
 →       →
 a = k * b


⑤ 벡터의 외적

> 방향과 크기를 동시에 가짐.

> 벡터 a&b로 이루어지는 평면에 수직하는 벡터가 나온다.

Crossproduct.png
FAL, https://commons.wikimedia.org/w/index.php?curid=334210

 평면벡터의 외적

 →    →   →    →
 a  x  b = a  ∧  b = |a||b| * sinΘ

  →                  →

 a = (a1, a2, a3), b = (b1, b2, b3) 일때,

 a  x  b

 => │ a1  a2  a3 │

      │ b1  b2  b3│

      │ x    y    z  │

=> (x y z) = (a2*b3-a3*b2, a1*b3-a3*b1, a1*b2-a2*b1)


⑥ 기타

> 단위벡터: 크기가 1인 벡터, 방향만 계산할때 유용.

> 일반벡터(Normal Vector): [#참조링크]






5. 미적분


* 미분<->적분의 관계

> 구체를 일정한 칸으로 자르면 미분, 칸칸히 잘랐던 오브젝트를 다시 붙이면 적분.


1) 삼각함수

① 그래프

Sine cosine plot.svg
By Qualc1 - Self-made using gnuplot and Inkscape This image was created with gnuplot., CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=762177

Tangent.svg
By No machine-readable author provided. Ktims assumed (based on copyright claims). - No machine-readable source provided. Own work assumed (based on copyright claims)., 퍼블릭 도메인, https://commons.wikimedia.org/w/index.php?curid=649670

특수각

> sinΘ:   0°=0, 30°=1/2, 45°=√2/2, 60°=(√3)/2, 90°=1

> cosΘ:  0°=1, 30°=(√3)/2, 45°=√2/2, 60°=1/2, 90°=0

> tanΘ:   0°=1, 30°=1/(√3), 45°=1, 60°=√3, 90°=∞


* 상단의 그래프 기준으로 1/2π당 사분면 1 영역과 대응되므로 그에 맞춰 루프등을 시키면 계산 가능.


② 연산

 덧셈정리

sin(α+β) = sinα*cosβ + sinβ*cosα

sin(α-β) = sinα*cosβ - sinβ*cosα      //[0, π]기준으로 각도가 클수록 값이 커서

con(α+β) = cosα*cosβ - sinα*sinβ

con(α-β) = cosα*cosβ + sinαβ*sinβ   //[0, π]기준으로 각도가 클수록 값이 작아서

tan(α+β) = (tanα+tanβ)/(1-tanαtanβ)

tan(α-β) = (tanα-tanβ)/(1+tanαtanβ)

 삼각함수간 관계

tanΘ = (sinΘ)/conΘ

(sinΘ)^2+(cosΘ)^2 = 1

1 + (tanΘ)^2 = (secΘ)^2

1 + (cotΘ)^2 = (cosecΘ)^2

 배각의 공식

sin2α = 2sinα*cosβ

cos2α = (cosα)^2 - (sinα)^2

         = 2*(cosα)^2 - 1 = 1 - 2*(sinα)^2

tan2α = (2*tanα) / (1-(tanα)^2)


sin3α = 3sinα - 4(sinα)^3

cos3α = 4*(cosα)^3 - 3*cosα

tan3α = (3*tanα-(tanα)^3) / (1-3*(tanα)^2)

 그외.

 반각공식 [#참조링크]

 곱<->합,차 변환



2) 미분종류별 미분공식

* 함수 f(x)에서 도함수 f'(x)를 구하는것을 함수를 x에 대하여 미분한다고 한다.

-> 도함수 f'(x) == y' == dy/dx == d/dx f(x)


① 기본 미분법

 ※ 다항함수

 f(x) = c [c는 상수]이면, f'(x) = 0

 {cf(x)}' = cf'(x)

 {f(x) ± g(x)}' = f'(x) ± g'(x)

 {f(x) * g(x)}' = f'(x)*g(x) + f(x)*g'(x)

 f(x) = (ax+b)^n [n은 자연수]일때,

          f'(x) = (ax+b)' * (ax+b)^(n-1)


 분수

> y = f(x)/g(x)

      = f(x) * (g(x)^-1)

   y' = {f'(x)*(g(x)^-1) + -1 * f(x)g'(x)}*{g(x)}^2

      = {f'(x)*(g(x)^-1) - * f(x)g'(x)}*{g(x)}^2

② 삼각함수

(sinΘ)' = cosΘ

(cosΘ)' = -sinΘ

(tanΘ)' = (secΘ)^2

          = 1+(tanΘ)^2


(cosecΘ)' = (1/sinΘ)'

             = -(1/sinΘ)*cotΘ

(secΘ)' = (1/cosΘ)'

          = secΘ * tanΘ

(cotΘ)' = (1/tanΘ)'

          = -(cosecΘ)^2

 [#참조링크, 삼각함수의 미분]
③ 로그함수&지수함수

 (ln x)' = 1/x [단, x>0]  //로그 밑수가 e면 ln으로 표기

 (logax)' = 1/(x * ln a) [밑수a>0, a!=1, x>0]

   -> 참고로 logax = log x/log a  [밑수는 10으로 생략]

   -> logax = 1/logxa

   -> logax * logxc = logac

 {ln |f(x)|}' = f'(x) / f(x)


 (e^x)' = e^x

 (a^x)' = a^x * lna --> a^x  [단, a>0]

 {e^f(x)}' = {e^f(x)} * f'(x)

 {a^f(x)}' = {a^f(x)} * lna * f'(x)

④ 편미분

 함수에서 x나 y를 상수로 간주한채 미분한다.

 예.

-> f = ax^2 + bxy + cy^2일때,

    ∂/∂x f = 2ax + by + 0

    ∂/∂y f = 0 + bx + 2cy

⑤ 그외

 N계도함수(or 고계도함수)

> 함수를 N번 미분하는것이다.

예. y = ax^2 + bx + c

    y' = 2ax + b

    y'' = 2a //2계 도함수



3) 미분과 활용

① 속도와 가속도

위치 x=f(t)일때

> (위치)' = 속도

>             (속도)' = 가속도


② 함수관련

 증가와 감수

 증가함수

> f'(x) ≥ 0

> f'(x) > 0인 구간에서 증가함수


 감소함수

> f'(x) ≤ 0

> f'(x) < 0인 구간에서 감소함수

 극대와 극소 극대/극소의 경우 f'(x) = 0인 값을 활용.

 평균값의 정리

 [#참조링크, 롤의 정리]

 [#참조링크, 평균값 정리]



4) 적분

① 부정적분

 ∫f(x) dx = F(x) + c

② 정적분

\int_{a}^{b} f(x)dx=\lim_{n \to \infty}  \sum_{k=1}^{n}f(x_k) \Delta x \quad \left( x_{k} = a + k \Delta x,\ \Delta x =\frac {b-a} {n} \right)

[#출처: 위키백과, 적분]


 미분된 함수 f(x)를 폐구간[a, b]를 기준으로 계산

 F(b) - F(a)

③ 2중 적분

 적분을 2중으로 계산하는것.

④ 활용법

 넓이와 부피






기타. 참조자료


WINNER 교육전략


[아꿈사] 게임 기초 수학 물리 1,2장

게임 프로그래머를 위한 기초 수학 및 물리 - [#8장][#9장]


게임 개발 포에버 :: Box2D Lite 소개 (물리엔진 공부의 좋은 시작)

게임에서 사용할 수 있는 포물선 운동