Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating body not accounting for delta time when only velocity is set? #637

Closed
wmike1987 opened this issue Jul 16, 2018 · 7 comments
Closed

Comments

@wmike1987
Copy link

wmike1987 commented Jul 16, 2018

I'm seeing differing body speeds (visually, not body.speed) when framerates differ. Movement is meant be framerate independent but it doesn't appear to be with respect to only velocity. I think this line is the issue (in Body.update()).

body.velocity.x = (velocityPrevX * frictionAir * correction) + (body.force.x / body.mass) * deltaTimeSquared;

body.velocity.y = (velocityPrevY * frictionAir * correction) + (body.force.y / body.mass) * deltaTimeSquared;

The logic here will disregard delta time if force == 0 and will thus update the body with the same velocity if our frame rate is 60 or 30. Am I missing something, or using the engine wrong?

Mike

@wmike1987
Copy link
Author

Any comment about this one?

@MDFL64
Copy link

MDFL64 commented Oct 29, 2018

I noticed this as well and I'm having a pretty hard time wrapping my head around it. I'm probably misunderstanding the math, but it seems like velocity isn't distance / time but is more like distance / timestep. I'm sure this makes sense to the engine but it makes dealing with and changing velocities super confusing.

@liabru
Copy link
Owner

liabru commented Nov 16, 2018

It does seem strange but this actually falls out of the math from position Verlet integration:

 xi+1 = xi + (xi - xi-1) + a * dt * dt

Check out this derivation, note that this assumes a constant time step. To account for a changing time step the author introduces a time correction scheme, which is what is implemented in the engine, though it's only intended for handling short dips since it's not that accurate. Hopefully that helps.

@wmike1987
Copy link
Author

wmike1987 commented Nov 18, 2018

Oh ok, thank you so much. I see how this all works now, indeed matter.js is implementing the time correction scheme proposed in that article, however calling setVelocity() on a body updates the body's previous position, which essentially sets the velocity to units per delta-time-of-last-frame rather than normalizing it to something like units per second, or whatever. So really I need to scale the initial velocity I give my bodies to mean the same thing regardless of frame rate.

@Qbyte248
Copy link

It does seem strange but this actually falls out of the math from position Verlet integration:

 xi+1 = xi + (xi - xi-1) + a * dt * dt

Check out this derivation, note that this assumes a constant time step. To account for a changing time step the author introduces a time correction scheme, which is what is implemented in the engine, though it's only intended for handling short dips since it's not that accurate. Hopefully that helps.

I think the formula is correct (see also Wikipedia Velocity integration).

According to my understanding, your code in Body.update calculates essentially

v[i] = (x[i] - x[i-1])
v[i+1] = v[i] + a * dt * dt
x[i+1] = x[i] + v[i+1]

However, velocities should be defined as the difference of current and previous position divided by the time step to make it "physically correct" i.e.

v[i] = (x[i] - x[i-1]) / dt
v[i+1] = v[i] + a * dt
x[i+1] = x[i] + v[i+1] * dt

This eliminates the strange dt * dt and the result of the position update is the same as before, but the velocity update is different/correct.

@liabru
Copy link
Owner

liabru commented Dec 29, 2020

@Qbyte248 it looks like you're assuming a fixed timestep there, which as it stands the engine does not assume, so it can't be simplified or rearranged that way in this case (you'll need a dt and a dt-1 term).

The latest discussion on this topic is found in the PR #777 which intends to normalise velocities among other things, please do try that out and help review if you're interested.

@liabru
Copy link
Owner

liabru commented Mar 16, 2023

Closing as I think this was covered by #777 which is now released in 0.19.0 (see the release notes). Thanks again.

@liabru liabru closed this as completed Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants