Sign in to follow this  
reaperrar

Basic time scaled movement

Recommended Posts

reaperrar    136
So lately for time scaled movement I've just been using this:
Position += Velocity * DeltaTime;

Which worked fine until I added acceleration...

Acceleration = (force * frictionforce) / mass
_____________________________________
Velocity += acceleration * DeltaTime;

Position += Velocity.

Problem is (if you haven't already spotted which you guys probably have) the velocity is no longer scaled.
Faster machines = faster objects ><

Here's an example of the math I did, comparing a machine that runs at one frame per second and a machine that runs at 5 frames per second.
Acc = 50 / second
Initial velocity = 0 / second

Machine 1
Time: - - - - 1.0
velocity: 0 0 0 0 50
Position: 0 0 0 0 50

machine 2
Time: 0.2 0.2 0.2 0.2 0.2
velocity: 10 20 30 40 50
Position: 10 30 60 100 150

So machine 2 (in this case) moves three times further than machine 1 in the same time span.

How can I fix this?

Share this post


Link to post
Share on other sites
Hodgman    51328
Part 1)
Scale velocity as well!! ([i]why did you stop scaling it when adding acceleration?[/i])[code]Velocity += acceleration * DeltaTime;
Position += Velocity * DeltaTime;[/code]Part 2)
The above will have fixed most of your issues, but the simulation will still be slightly different on two computers if the frame-rate changes. You can solve this by using a more robust numerical integration technique (the one you're currently using is called [url="http://en.wikipedia.org/wiki/Euler_method"]Euler's method[/url]).
Or, what most people do is to simply use a [url="http://gafferongames.com/game-physics/fix-your-timestep/"]fixed time-step[/url], which makes both computers produce the same result despite the use of an approximate integrator.

Share this post


Link to post
Share on other sites
reaperrar    136
If I scale both, won't my position end up like this:

machine 2
Time: 0.2 0.2 0.2 0.2 0.2
velocity: 10 20 30 40 50
ScaledVel: 2 4 6 8 10
Position: 2 6 12 20 30

Share this post


Link to post
Share on other sites
Hodgman    51328
30 is closer to 50 than 150 is.

Remeber that the [url="http://en.wikipedia.org/wiki/Equations_of_motion"]formula you're trying to implement[/url] here does scale velocity by time, and scales acceleration by time twice:
[font="Courier New"][img]http://upload.wikimedia.org/math/9/1/3/91372d6d7dbb07b5d2a9220bf3ebf443.png[/img][/font]


See part 2 to fix the rest.
When using a numerical integrator, the size of your steps affects the accuracy of the result ([i]these techniques only give [b]estimated [/b]results![/i]). So, because both computers have used different step sizes, they've come out with different estimations of the answer.

Share this post


Link to post
Share on other sites
reaperrar    136
I wish I took physics now ><

[quote]See part 2 to fix the rest.[/quote]
Equation 2 on the wikipedia page you linked?

Also looking at that page, what's the difference between "s0" and "si"? They both appear to be initial position.

Lastly...
[quote][i]these techniques only give [b]estimated [/b]results![/i][/quote]
What's the most accurate technique for movement/acceleration scaled with time?

Share this post


Link to post
Share on other sites
Hodgman    51328
[quote name='reaperrar' timestamp='1307938552' post='4822606']
Equation 2 on the wikipedia page you linked?[/quote]No, in my earlier post, there was a "Part 2)" section where I said that [i]using[/i] [i]an approximate integrator isn't a problem [/i]as long as you used a [url="http://gafferongames.com/game-physics/fix-your-timestep/"]fixed time-step[/url].

e.g. Instead of something like:[code]deltaTime = ....//time since last frame
Update( deltaTime );[/code]You want something like:[code]deltaTime = .... //time since last frame
deltaTime += m_leftOverTimeFromLastFrame;
const double timeStepSize = 1/60.0f;//60 updates per second
while( deltaTime > timeStepSize )
{
Update( timeStepSize ); //N.B. update is always called with the same (fixed) time step value
deltaTime -= timeStepSize;
}
m_leftOverTimeFromLastFrame = deltaTime;//there might be half a step left over, save it for next frame.[/code][quote]Also looking at that page, what's the difference between "s0" and "si"? They both appear to be initial position.[/quote]Yeah they're the same :/[quote]What's the most accurate technique for movement/acceleration scaled with time?[/quote]Your current method ([i]Euler's method[/i]) is fine, assuming that you're using a fixed-time step as above -- the smaller the time-step, the more accurate it will be (but also will take more CPU time).
However, if you do want it to be more accurate for whatever reason, you can try [url="http://gafferongames.com/game-physics/integration-basics/"]RK4[/url].

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this