When dealing with motion of objects in space in realtime under some theoretical locomotion, one ordinarily deals with giving that object a velocity and letting it proceed by its own momentum. Its is under these circumstances that I posted the following to rec.games.programmer some time ago.

Changing motion should be acheived by changing "v" and/or (x1,y1) in an AI, or player update phase of your application. However if your goal is to take gravity into account then you might proceed as follows:Suppose you have: Starting postiton: (x0,y0) Ending position: (x1,y1) Velocity: v Elapsed time: t Then compute your hypontenuse *once*; i.e., when you compute the destination position, and velocity, also compute the hypontenuse between the two points. So you can assume you also have: Hypotenuse: h = sqrt( (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1) ); Then for a given elapsed time (since your sprite was at its starting point) you get the current position (x,y) as: x = x0 + ((x1-x0) * v * t) / h; y = y0 + ((y1-y0) * v * t) / h; Once (t * v) has equalled or exceeded h, you know that the sprite has reached or exceeded its end point. As a simple optimization you can precompute (x1-x0) and (y1-y0). Simple physics. For accuracy reasons its important to maintain the old (x0,y0) as well as the target (x1,y1) (or (x1-x0,y1-y0) which would be equivalent), the variables v,t and h should be floating point values and the equations given above should be computed with the give order of operations. This will allow you to maintain x,y,x0,y0,x1,y1 as integers if you wish. If you use floating point variables only, you can relax the order of operation requirements and precompute (v/h) beforehand. This would also allow you to drop the values of (x0,y0) and use an incremental approach (using delta t, rather than t since starting) but then the end detection strategy has to change. The advantage of the floating point method is that you can avoid an extra divide (which is nasty) and you have the opportunity to use the FPU for calculations. The disadvantage is that most graphics libraries prefer to receive integer coordinates, hence a conversion is required.

Suppose you have: Starting height: z0 Starting Velocity: v0 Acceleration constant: a Absolute terminal velocity: vt Elapsed time: t Here everything is considered in floating point notation. Then the new height and velocity would be computed as: z = (a/2)*(t * t) + (v0 * t) + z0 v = v0 + (a * t) The velocity "v" is ordinarily clamped by the "terminal velocity" beyond which the velocity can never go above or below. Once the velocity reaches "terminal velocity" (i.e., abs(v0)>=vt) the height should be updated linearly as follows: z = (v0 * t) + z0 If the update causes the velocity to go from non-terminal to terminal (abs(v0 + a * t)>=vt>abs(vo)) then for complete accuracy you should compute the update in two parts by first calculating the two time intervals t0 and (t-t0) according to: t0 = (vt*sgn(v0 + (a * t)) - v0)/a Then iterate the two updating formulae above in order according to z0 <- z and v0 <- v first with t <- t0 then with t <- (t-t0). sgn is a function returning 1, 0, -1 depending on the sign of the argument, such that x == abs(x)*sgn(x). Note that it makes little sense to perform these computations in more than one axis at a time. You should orient your Z-axis to point towards the center of gravity. If this is not possible then you end up with an acceleration and velocity vector, rather than constants above. If you have more than one gravitational force, then you have to use an "n-body" solutions to the problem. There is a well known approximation method that uses differences on the taylor expansion of the motion path vectors which acheives accuracy on the order of the fourth derivative multiplied by a smallish factor.

Copyright © 1996, Paul Hsieh All Rights Reserved.