Physics - Projectile
[TOC]
등가속도
\[\begin{gather*} \begin{array}{ c c c } t & : & 경과\ 시간\\ a & : & 가속도\\ v_{0} & : & 처음\ 속도\\ v & : & 나중\ 속도 \end{array}\\ a=\frac{v-v_{0}}{t} \end{gather*}\]속도
\[\begin{gather*} \begin{array}{ c c c } t & : & 경과\ 시간\\ a & : & 가속도\\ v_{0} & : & 처음\ 속도\\ v & : & 나중\ 속도 \end{array}\\ v=v_{0} +at \end{gather*}\]물체의 변위(이동 거리)
\[\begin{gather*} \begin{array}{ c c c } s & : & 변위 \end{array}\\ s=v_{0} t+\frac{1}{2} at^{2} \end{gather*}\]시간이 주어지지 않았을 때 물체의 변위
\[\begin{gather*} v=v_{0} +at를\ t로\ 정리\\ t=\frac{v-v_{0}}{a}\\ \\ 물체의\ 변위식의\ t에\ 대입\\ \begin{array}{ c c c } s & = & v_{0} t+\frac{1}{2} at^{2}\\ & = & v_{0}\left(\frac{v-v_{0}}{a}\right) +\frac{1}{2} a\left(\frac{v-v_{0}}{a}\right)^{2}\\ & = & \frac{vv_{0} -v^{2}_{0}}{a} +\frac{v^{2} -2vv_{0} +v^{2}_{0}}{2a}\\ & = & \frac{2vv_{0} -2v^{2}_{0} +v^{2} -2vv_{0} +v^{2}_{0}}{2a}\\ & = & \frac{v^{2} -v^{2}_{0}}{2a} \end{array}\\ \\ \therefore 2as=v^{2} -v^{2}_{0} \end{gather*}\]포물선 운동
포물선 - t초 후 속도
\[\begin{equation*} \begin{array}{ c c c } v_{x} & = & v_{0}\cos \theta \ ( 수평은\ 등속운동)\\ v_{y} & = & v_{0}\sin \theta -gt \end{array} \end{equation*}\]포물선 - t초 후 위치
\[\begin{equation*} \begin{array}{ c c c } x & = & v_{0}\cos \theta \times t\\ y & = & v_{0}\sin \theta \times t-\frac{1}{2} gt^{2} \end{array} \end{equation*}\]포물선 - 최고점 높이
\[\begin{gather*} 최고점에서\ y속도가\ 0이\ 되는\ 것을\ 이용\\ \\ \begin{array}{ c c c c } 2as & = & v^{2} -v^{2}_{0} & \\ -2gs & = & 0-v^{2}_{0} & ( g는\ 반대방향이므로\ -,\ 최고점\ 속력은\ 0)\\ 2gs & = & v^{2}_{0} & \\ 2gs & = & v^{2}_{0y} & ( y의\ 변위를\ 구하므로\ v_{0y} 로\ 변경)\\ 2gs & = & ( v_{0}\sin \theta )^{2} & \\ s & = & \frac{( v_{0}\sin \theta )^{2}}{2g} & \\ s & = & \frac{v^{2}_{0}\sin^{2} \theta }{2g} & \end{array}\\ \therefore h( 최고점\ 높이) =\frac{v^{2}_{0}\sin^{2} \theta }{2g} \end{gather*}\]포물선 - 최고점 도달 시간
최고점에서 y속도는 0, 등가속도는 중력가속도 g를 시간을 구하는 공식에 대입
\[\begin{gather*} \begin{array}{ c c c c } t & = & \frac{v-v_{0}}{a} & \\ & = & \frac{0-v_{0}}{g} & \\ & = & \frac{v_{0}\sin \theta }{g} & ( y축에\ 대한\ 식으로\ 변경) \end{array}\\ \therefore h_{t}( 최고점\ 도달\ 시간) =\frac{v_{0}\sin \theta }{g} \end{gather*}\]포물선 - 수평 도달 거리
이동 거리 공식에 최고점 도달시간 공식의 2배를 대입
(땅에 떨어질 때까지의 시간은 최고점 도달 시간의 2배)
\[\begin{gather*} \begin{array}{ c c c c } s & = & vt & ( 이동거리\ 공식)\\ & = & v_{0}\cos \theta \times t & ( x에\ 대한\ 식으로\ 변경)\\ & = & v_{0}\cos \theta \times \left( 2\times \frac{v_{0}\sin \theta }{g}\right) & ( 최고점\ 도달시간\ 공식\ 대입)\\ & = & \frac{v_{0}\cos \theta \times 2v_{0}\sin \theta }{g} & \\ & = & \frac{v^{2}_{0} \times 2\cos \theta \sin \theta }{g} & \\ & = & \frac{v^{2}_{0} \times \sin 2\theta }{g} & (\sin 2\theta =2\cos \theta \sin \theta ) \end{array}\\ \therefore r( 수평\ 도달\ 거리) =\frac{v^{2}_{0} \times \sin 2\theta }{g} \end{gather*}\]포물선 - 경로 방정식
처음 속도와 발사 각도 및 x값을 아는 경우 y값을 계산할 수 있다.
x의 변위식을 y의 변위식에 대입하여 방정식 도출
\[\begin{gather*} \begin{array}{ c c c c } s & = & v_{0} t-\frac{1}{2} gt^{2} & ( 거리\ 기본식)\\ x & = & v_{0}\cos \theta t & \\ y & = & v_{0}\sin \theta t-\frac{1}{2} gt^{2} & \end{array}\\ \\ x식을\ t에\ 대해\ 정리\ 후\ y식에\ 대입\\ \\ \begin{array}{ c c c c } t & = & \frac{x}{v_{0}\cos \theta } & \\ y & = & v_{0}\sin \theta \frac{x}{v_{0}\cos \theta } -\frac{1}{2} g\left(\frac{x}{v_{0}\cos \theta }\right)^{2} & ( t를\ 대입)\\ & = & \frac{v_{0}\sin \theta }{v_{0}\cos \theta } x-\frac{1}{2} g\frac{x^{2}}{v^{2}_{0}\cos^{2} \theta } & \\ & = & \tan \theta x-\frac{g}{2v^{2}_{0}\cos^{2} \theta } x^{2} & \left(\frac{\sin \theta }{\cos \theta } =\tan \theta \right) \end{array} \end{gather*}\]using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ProjectileMotionTest : MonoBehaviour
{
[Range(0, 360)]
public float Angle;
public float Velocity;
public float Gravity = 9.8f;
public float XRange = 10f;
public float DrawLineResolution = 50;
private void OnDrawGizmos()
{
// 각도와 속도 그리기
float radian = Angle * Mathf.Deg2Rad;
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, transform.position + new Vector3(Velocity * Mathf.Cos(radian), Velocity * Mathf.Sin(radian), 0));
// 포물선 그리기
Gizmos.color = Color.red;
float xUnit = XRange / DrawLineResolution;
Vector3 prevPosition = transform.position;
for (int i = 0; i < DrawLineResolution; i++)
{
float x = xUnit * i;
float y = GetProjectileMotionY(x);
Vector3 curPosition = transform.position + new Vector3(x, y, 0);
Gizmos.DrawLine(prevPosition, curPosition);
prevPosition = curPosition;
}
}
private float GetProjectileMotionY(float x)
{
float radian = Angle * Mathf.Deg2Rad;
float y = Mathf.Tan(radian) * x;
y -= Gravity / (2 * Velocity * Velocity * Mathf.Cos(radian) * Mathf.Cos(radian)) * (x * x);
return y;
}
}
포물선 - (역)경로 방정식
최고점 높이(h), 최고점 도달 시간(ht), 마지막 위치(y) 및 경과 시간(t)을 아는 경우 y값을 계산할 수 있다.
1. g(등가속도)값 구하기
최고점에서 지면으로 떨어질 때 최초 속도는 0이고 이동 거리(최고점 높이), 도달 시간을 알고 있으므로 기본공식을 이용하여 g값을 계산할 수 있다.
최고점에서 떨어지는 운동은 중력가속도에 의해 가속되는 운동이므로 등가속도값 빼지 않고 더해준다.
\[\begin{equation*} \begin{array}{ c c c c } y & = & v_{0}\sin \theta \times t+\frac{1}{2} gt^{2} & \\ h & = & 0\times \sin \theta \times t+\frac{1}{2} gt^{2} & \\ & = & \frac{1}{2} gt^{2} & \\ g & = & \frac{2h}{t^{2}} & \end{array} \end{equation*}\]2. y의 초기 속도(vy) 구하기
g값을 구했으니 최고점 높이 구하는 공식을 이용해 y의 초기 속도를 계산한다.
\[\begin{equation*} \begin{array}{ c c c } h & = & \frac{v^{2}_{0}\sin^{2} \theta }{2g}\\ & = & \frac{v^{2}_{y}}{2g}\\ v^{2}_{y} & = & 2hg\\ v_{y} & = & \sqrt{2hg} \end{array} \end{equation*}\]3. 마지막 위치(y)까지 이동 시간(t) 구하기
기본 이동 공식에 알고 있는 값을 대입하면 미지수가 t만 남는데 이는 근의 공식을 사용하여 계산해 낸다.
\[\begin{gather*} y=v_{y} t-\frac{1}{2} gt^{2}\\ \begin{array}{ c c c } -\frac{1}{2} gt^{2} +v_{y} t-y & = & 0\\ gt^{2} -2v_{y} t+2y & = & 0 \end{array}\\ \\ x=\frac{-b+\sqrt{b^{2} -4ac}}{2a}( 근의\ 공식)\\ \\ \begin{array}{ c c c } a & = & g\\ b & = & -2v_{y}\\ c & = & 2y \end{array}\\ \\ \therefore t=\frac{2v_{y} +\sqrt{( -2v_{y})^{2} -8gy}}{2g} \end{gather*}\]4. x의 초기속도(vx) 구하기
\[\begin{gather*} x( 마지막\ 위치) =v_{x} \times t\\ v_{x} =\frac{x}{t} \end{gather*}\]5. 경과 시간값을 변화시키며 좌표얻기
t초 후 위치 계산 식에 t값을 변화시키며 좌표를 얻는다.
\[\begin{equation*} \begin{array}{ c c c } x & = & v_{x} t\\ y & = & v_{y} t-\frac{1}{2} gt^{2} \end{array} \end{equation*}\]using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class ParabolaAlgorithm
{
public float HeightLimit { get; private set; }
public float TimeToTopmostHeight { get; private set; }
public float TimeToEndPosition { get; private set; }
private Vector3 _startPosition;
private Vector3 _endPosition;
private float _vx;
private float _vy;
private float _gravity;
public Vector3 GetPosition(float elasedTime)
{
float x = _vx * elasedTime;
float y = (_vy * elasedTime) - (0.5f * _gravity * elasedTime * elasedTime);
return new Vector3(_startPosition.x + x, _startPosition.y + y, 0f);
}
public void Init(float heightLimit, float timeToTopmostHeight, Vector3 startPosition, Vector3 endPosition)
{
this.HeightLimit = heightLimit;
this.TimeToTopmostHeight = timeToTopmostHeight;
_startPosition = startPosition;
_endPosition = endPosition;
CalcParabolaTrack();
}
private void CalcParabolaTrack()
{
float endHeight = _endPosition.y - _startPosition.y;
float height = HeightLimit;
//float height = MaxHeight - transform.position.y;
_gravity = 2 * height / (TimeToTopmostHeight * TimeToTopmostHeight);
_vy = Mathf.Sqrt(2 * _gravity * height);
float a = _gravity;
float b = -2 * _vy;
float c = 2 * endHeight;
TimeToEndPosition = (-b + Mathf.Sqrt(b * b - 4 * a * c)) / (2 * a);
//Debug.Log(TimeToEndPosition.ToString("#.###"));
_vx = (_endPosition.x - _startPosition.x) / TimeToEndPosition;
}
}
참고
http://blog.naver.com/PostView.nhn?blogId=whwodud98&logNo=50103673919
https://www.slideshare.net/semin204/ss-16331290
https://0mind.tistory.com/entry/%ED%8F%AC%EB%AC%BC%EC%84%A0%EC%9A%B4%EB%8F%99-%EA%B3%B5%EC%8B%9D