fix Shot trajectory calculation

This commit is contained in:
Josh Holtrop 2012-10-07 07:54:38 -04:00
parent 1741476456
commit f1809bf193

View File

@ -9,43 +9,48 @@ using namespace sf;
* starts at, which will depend on the tank model in use */ * starts at, which will depend on the tank model in use */
#define INITIAL_SHOT_HEIGHT 10 #define INITIAL_SHOT_HEIGHT 10
#define GRAVITY 9.8 /* GRAVITY can really be any arbitrary value that makes the shot's speed
* feel right. Increasing the gravity will decrease the amount of time
* it takes the shot to hit its target. */
#define GRAVITY 30
/* We model the shot's position using a parametric equation based on time. /* We model the shot's position using a parametric equation based on time.
* Assuming a constant 45° shot angle simplifies the equations. * Assuming a constant 45° shot angle simplifies the equations.
* x = Vt * x = vt
* y = H + Vt - gt²/2 * y = h + vt - gt²/2
* = (-g/2)t² + Vt + H * = (-g/2)t² + vt + h
* where * where
* V = shot speed * v = shot speed
* t = time * t = time
* g = gravity * g = gravity
* H = INITIAL_SHOT_HEIGHT * h = INITIAL_SHOT_HEIGHT
* *
* We want to figure out a speed that gets us to y = 0 at our desired time. * Given a target distance of d, we want to figure out a speed that makes
* According to the quadratic formula (x = (-b ± sqrt(b²-4ac))/2a), y = 0 when * (x, y) = (d, 0) a valid point on the trajectory.
* t = (-V ± sqrt(V² - 4(-g/2)H)) / 2(-g/2) * Then:
* -tg = -V ± sqrt(V² + 2gH) * d = vt
* V - tg = ± sqrt(V² + 2gH) * 0 = (-g/2)t² + vt + h
* * So:
* V - tg = sqrt(V² + 2gH) * v = d/t
* (V - tg)² = V² + 2gH * 0 = (-g/2)t² + (d/t)t + h
* V² - 2Vtg + t²g² = V² + 2gH * 0 = (-g/2)t² + d + h
* t²g² - 2Vtg = 2gH * According to the quadratic formula (x = (-b ± sqrt(b² - 4ac))/2a),
* -2Vtg = 2gH - t²g² * t = ±sqrt(-4(-g/2)(d+h)) / 2(-g/2)
* V = -(2gH - t²g²)/2tg * -tg = ±sqrt(2g(d+h))
* V = (t²g² - 2gH)/2tg * t²g² = 2g(d+h)
* * t² = 2(d+h)/g
* So given the time to target (target_dist / PROJECTILE_VELOCITY) we can * t = sqrt(2(d+h)/g)
* solve for what the shot's speed should be. * Now that we know the time at which this point occurs, we can solve for
* the shot speed (v)
* v = d/t
* v = d / sqrt(2(d+h)/g)
*/ */
Shot::Shot(const Vector2f & origin, double direction, double target_dist) Shot::Shot(const Vector2f & origin, double direction, double target_dist)
{ {
m_direction = Vector2f(cos(direction), sin(direction)); m_direction = Vector2f(cos(direction), sin(direction));
m_origin = origin; m_origin = origin;
double t = target_dist / PROJECTILE_VELOCITY; m_speed = target_dist /
m_speed = (t * t * GRAVITY * GRAVITY - 2 * GRAVITY * INITIAL_SHOT_HEIGHT) sqrt(2 * (target_dist + INITIAL_SHOT_HEIGHT) / GRAVITY);
/ (2 * t * GRAVITY);
} }
Vector3f Shot::get_position() Vector3f Shot::get_position()