Raven
Raven

Reputation: 4903

Ballistic curve problem

Ok i know this is quite off-topic for programmers but still I need this for app, so here it is:

Ballistic curve (without wind or any other conditions) is specified by these 2 lines:

x coordinate

y coordinate

So, there is a problem that you got 3 unknown values: x,y and time t, but only 2 equations. You can't really compute all 3 with just these values, I got:

Thus, you have to decide which one to specify.

Now you have 2D tanks game, or anything like that, you know you have tank and using ballistic you have to shoot opponent down with setting angle and power.

I need to know when the bullet hit the ground, it can be on-air as it fly, or precomputed. There comes up my problem. Which way to use? Pre-compute or check for hitting the ground in each step.

If I would like to pre-compute, I would need to know height of terrain, which, logically would have to be constant as I don't know in which x coord. If I would know the X, it would mean that just in front of my turret is wall. So only way to get to result, when I hit the ground, would be with checking in intervals of time for hitting the ground. This is also good because the terrain doesn't have top be static yay! But isn't that too great overhead which could be made much simpler? Have you encountered with such problem/solution?

Thanks in advance, btw the terrain can be flat, using lines or NURBS so I please for general solution, not specific as in which height you shoot in that will be impact.

Upvotes: 13

Views: 5206

Answers (5)

rtm
rtm

Reputation: 194

Continuous functions do not work well for computers, because computers are implicitly discrete: the floating/double numbers are discrete, the timer is discrete, the game grid is discrete (even if it uses 'doubles').

So just discretize the equation the way Justin Holdsclaw suggested. Have velocity and accelerations vectors in each direction (in your case X and Y; you could also add Z). Update all vectors, and the object's position in space, at every tick.

Note that the result won't be 'exact'. The smaller your 'delta' values (grid coarseness), the closer you'll be to the 'exact' curve. To know precisely how close - if you're interested, find a book on numerical analysis and read the first few chapters. For practical purposes you can just experiment a bit.

Upvotes: 0

Justin Holdsclaw
Justin Holdsclaw

Reputation: 101

David Zaslavsky did a good job of answering your question about solving for the equation, but if your ultimate goal is simple ballistics simluation, I suggest you instead use vector decomposition.

By utilizing vector decomposition, you can derive the x- and y-compenent vectors of your projectile. You can then apply acceleration to each component to account for gravity, wind, etc. Then you can update the projectile's (x,y) position each interval as a function of time.

For example:

double Speed = 100.0;     // Speed rather than velocity, as it is only the magnitude
double Angle = 30.0;      // Initial angle of 30º
doulbe Position[2] = {0.0,0.0};  // Set the origin to (0,0)

double xvelocity = Speed * Cos(Angle);
double yvelocity = Speed * Sin(Angle);

Then if you can impliment a simple Update function as follows:

void Update(double Time)
{
     yvelocity = -9.8 * Time; // Apply gravity

     Position[0] *= (xvelocity * Time);  // update x position
     Position[1] *= (yvelocity * time);  // update y position

     CheckCollisions();  // check for collisions
}

Of course this is a very basic example, but you can build on it from here.

Upvotes: 6

plinth
plinth

Reputation: 49179

I'm not sure you're going about this is right way. The main equation you want is s = si + vi*dt + .5*adtdt. This is a simple equation of one dimension, but it generalizes to vectors cleanly.

Effectively, si is your initial position and vi is your initial velocity and a is acceleration due to gravity.

To make this work, build a vector for perfect horizontal muzzle velocity and project it on the launch angle. That's your vi. Si will be the tip of the barrel. From there it's vector summing and scaling.

Upvotes: 1

Carl Smotricz
Carl Smotricz

Reputation: 67750

Fortunately, this is pretty simple kinematics.

Those equations are parametric: For any given time t, they give you the x and y coordinates for that time. All you need to do is plug in the starting velocity v and angle a.

If you're working on level ground, the time for your projectile to come back down is simply 2sin(a)v/g, i.e. the vertical component of your velocity divided by the downward acceleration due to gravity. The 2 is because it takes that amount of time for the speed to drop to 0, then the same time again for it to accelerate back down. Once you know the time you can solve for x.

If your terrain is not flat, you have some additional fun. Something you could try is work out the time for hitting the ground at the same height, and then correct for the extra vertical distance. This will also change your horizontal distance which might again affect your height... but two or three adjustments and the error will be too small for humans to notice :)

Upvotes: 5

David Z
David Z

Reputation: 131550

You can compute the path of the projectile y(x) by solving one equation for t and substituting into the other. You get

y = x tan(theta) - x^2g/2(v cos(theta))^2

Then finding the landing point is a matter of computing the intersections between that function and the function that defines the height of the terrain. One intersection will be the launch point and the other will be the landing point. (If your terrain is very steep and hilly, there could be more than 2 intersections, in which case you take the first one with x greater than the launch point.) You can use any of various root-finding algorithms to actually compute the intersection; check the documentation of whatever mathematical or game-physical libraries you have to see if they provide a method to do this.

Upvotes: 17

Related Questions