Search code examples
math2d-games

equation to get curve for simulating friction for a game


I want to very roughly simulate friction on particles from a top-down point of view. The particles should tend to come to a halt when they are going slow and experience less friction (relative to their velocity) the faster they are going. It should look something like this... enter image description here

At the moment friction (a force applied to the particles every frame) = -(velocity*constant1 - velocity^2*constant2 )*deltatime

Can someone suggest a better way of doing this?


Solution

  • Usual friction

    Usually friction is caused by speed and modeled in simple models by something like, say, - c v^2.

    That means that if your particles have a force attracting them (e.g. gravity), then at some point friction evens it out and your particles reach a maximum constant velocity.

    With the friction formula in your example, it eventually decreases and even reaches a positive value for big enough velocities, thus pushing the particles in the direction of their speed, which is kind of strange. In any case, friction forces that do not monotonously increase with speed are suspect.

    The behaviour you describe by saying "experience less friction relative to their velocities the faster they are going", can be expressed mathematically by saying that you want a function that diverges less quickly than the identity. Formally, you are looking for a function f(x) such that f(x)/x converges towards 0 when x goes to infinity.

    Let us leave aside functions that converge to a finite value (possibly 0), as they don't seem intuitive : the faster you go, the more friction you should have.

    Functions you can use

    Functions that diverge slower than x but still diverge are typically the powers of x with degrees in ]0,1[ (0 and 1 excluded). A good example is 0.5, a.k.a the square root of x.

    Furthermore, another good fit is the log function, that diverges very slowly.

    Then you can take any linear combination of the above, and even powers of the log.

    Behaviour for small velocities

    Now on your graph, the red line is always below the grey one, which isn't the case for a function x^a as described above. You probably want something that is 0 in x=0, since it doesn't make much sense even with your model to see a particle turn around and go back when it reaches speed 0. To comply to both requirements, you again have several options.

    • piecewise functions. Trivial, possibly easy to compute. Say you use x^0.83 on the interval [1,+inf[ and something that is 0 in x=0 and 1^0.83=1, in x=1, on the interval [0,1[. Typically something as trivial as x itself.

    • shifting the function, typically by 1 (that is enough for all the cases we look at). For the log this is pretty straightforward, since it diverges towards -inf in 0, and is 0 in 1, you should for your use never take log(x) but rather log(1+x). For powers, they behave like we want ("below the red line") for x > 1. To keep the property of a null friction when x=0, you need to shift in a fashion like : f(x)=(1+x)^a-1 with a in ]0,1[

    Customizing to your taste

    Now that you have all this, I would recommend you to try to plot a few of these functions. Pick the one that seems the most appropriate, you can typically chose how slow to increase by picking either the log (as slowest) or any power function (knowing that the bigger the power, the faster the increase in friction relative to velocity). You can also stretch the curve to increase faster or slower but keep the same "curvature", by dilating the curve, i.e. replace x by x/a or a * x. For example, with x^0.8, you can get this function : http://fooplot.com/plot/b7a0whkcdz

    Only you know what kind of forces apply on the particles (which is with what you should compare the output values of the function, thus the f(x)), and what velocities are typical for the particles (thus over which x your function should span with acceptable values), so I cannot help you with that.

    Then try some experiments with your game to adjust your parameters, and voilà ! You're done.