Home Game Development physics – Friction using delta time returns inconsistent result

physics – Friction using delta time returns inconsistent result

0
physics – Friction using delta time returns inconsistent result

[ad_1]

This line assumes that yVel is constant for the entirety of the duration delta:

this.y += this.yVel * delta;

But that’s not true – we know by the end of duration delta that yVel has decreased to a fraction of \$0.99^\text{delta}\$ according to this line:

this.yVel *= Math.pow(0.99, delta);

So if we think of yVel as a function of time, \$v(t) = v_0 \cdot 0.99^t\$, then the total displacement in y over the course of the interval delta is the integral:

$$\begin{align}
\Delta y &= \int_0^\text{delta}v_0 \cdot 0.99^t dt\\
&= v_0 \cdot \int_0^\text{delta} e^{\ln (0.99) \cdot t} dt\\
&= v_0 \cdot \left( \frac 1 {\ln(0.99)} e^{\ln(0.99) \cdot t}\right)\Bigg|^\text{delta}_0\\
&= \frac {v_0} {\ln(0.99)}\left(e^{\ln(0.99)\cdot \text{delta}} – 1 \right)\\
&=v_0 \cdot \frac {0.99^\text{delta} – 1} {\ln(0.99)}
\end{align}$$

In code:

var frictionFactor = Math.Pow(0.99, delta);
this.y += this.yVel * (frictionFactor - 1)/Math.Log(0.99);
this.yVel *= frictionFactor;

This will be smoother, but can still vary from one run to another due to limited precision and accumulation of rounding errors. So as Shin Dongho mentioned, your best bet here is to fix your physics timestep at a known value, so you get consistent, reproducible results.

[ad_2]