views:

277

answers:

5

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:

  • velocity v
  • angle Alpha
  • origin coordinates

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.

+17  A: 

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.

David Zaslavsky
ok I get it now, this is actualy pretty simple. Should you supply me with the of solving these equations? I know it's wikipedia one, but you might seen it around. I'll search for it otherwise. The problem is that I done this before but the equation was pretty ugly, now this one above is about half of mine. It's just about substituing etc. but I didn't got that far in solving equations, I think I have to learn these sines and cosines substitutions... so anyway thanks for really good answer :)
Raven
@David, doesn't this result in a discontinuity at 90 degrees?
MSN
I think it would be a good idea to get rid of the trigonometry right at the start: Get your initial velocity and angle, and then calculate vx = v0cos(a) and vy = v0sin(a) and go on working from those two. Your x motion is just vx times the time spent in the air; the only part with funky (quadratic) math is the y motion. Should be a lot easier if looked at like that, though.
Carl Smotricz
@MSN with my math knoweledge that's true because tan(90) would give error, so there have to be special cases. @Carl recommending on-air checking for collision then? (I think so as you wrote it just :D )
Raven
@MSN: yes it does, although in physics we usually consider "projectile motion" to encompass only cases with launch angle <90 degrees. The 90-degree case has to be handled specially but it's completely trivial: the landing point is the same as the launch point.
David Zaslavsky
@Carl: computing `v_x` and `v_y` at the start would indeed be a good idea. But if the terrain is not flat, figuring out the time the projectile spends in the air becomes rather complicated. In fact the easiest way to do so (AFAIK) would be to first intersect the path with the terrain as I described, and then compute `t = x/v_x`.
David Zaslavsky
+5  A: 

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 :)

Carl Smotricz
Your last paragraph pretty much describes Newton's method, I think ;-)
David Zaslavsky
I'm hoping to harvest energy from his in-grave rotation. I actually got two Sir Isaac Newton prizes for physics at my High School, but that's a long time ago and I was too lazy to look up the details. Also, I didn't want to overwhelm the OP with reams of equations. In my defense, it's customary to use quick-n-dirty shortcuts in game programs for efficiency's sake :)
Carl Smotricz
Don't get me wrong - I wasn't saying there was anything wrong with your answer! (I upvoted you) Just pointing out something for the curious.
David Zaslavsky
+1  A: 

I'm not sure you're going about this is right way. The main equation you want is s = si + vi*dt + .5*a*dt*dt. 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.

plinth
+4  A: 

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.

Justin Holdsclaw
yes and that is what I mean... David's answer is really helpfull but one thing wasn't asnwered and that is if I should use dynamic checking for collision or precompute values.
Raven
@Raven: I wrote my answer under the assumption that you were asking about how to precompute the landing point. The question of whether you should do that or dynamically check for a collision depends on your program - if it's a simulation-type thing, you might as well just do the collision check at each time step, in which case this answer is a fine starting point. (+1) (note that there are sophisticated algorithms for getting a more accurate simulation, which are probably used in whatever physics engine you're using)
David Zaslavsky
@Raven: As David points out, the best solution always depends on what the problem is. If you have a fairly static environment, perhaps a precompiled outcome will suffice. However, as more variables and/or unknowns are introduced, it becomes more practical to perform your checks dynamically and on-the-fly.
Justin Holdsclaw
A: 

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.

JackKane