3
votes

I'm writing a little game with a top-down view of some sliding objects, like curling or shuffleboard. (I happen to be using PyMunk for the physics, but since this question is about physics simulations in general, don't worry about language specifics.) Before I start tweaking all the values in my little sim to get behaviour that 'feels' right, I thought I'd better check to make sure that I'm at least modelling the right kind of velocity curve in the first place. However, finding a clear answer about this has turned out to be substantially harder than expected.

Model A

To simulate the way an object slides to a halt, pymunk allows the programmer to set space.damping, which works like this (quoting from the API reference): "A value of 0.9 means that each body will lose 10% of its velocity per second."

That makes sense, but it seems that that would produce a velocity-over-time curve with this basic shape (never mind the exact numbers):

     |*
  v  |       
  e  | 
  l  | *               
  o  |  
  c  |  * 
  i  |    *
  t  |      *****     
  y  |           ****************
     ---------------------------*---- 
             time

In other words, acceleration decreases over time. (Some might prefer to say "deceleration" or "negetive acceleration" decreases, but in the purest physics sense any change in velocity is 'acceleration', and in the chart above the change in velocity becomes smaller over time.) Because such a curve will approach but never cross 0, a cutoff is employed under which a body's velocity is forced to 0. Pymunk provides a setting for the cutoff, too: space.idle_speed_threshold.

This seems straightforward enough but gave rather unsatisfying results when I tried it in my little simulation. So, I began to consider Model B, below.

Model B

Thinking about it intuitively, it seems like the acceleration would increase over time, making a curve like this:

     |********
  v  |        ******
  e  |              ****
  l  |                  ***
  o  |                     ***
  c  |                        **
  i  |                          **
  t  |                            *
  y  |                             *
     -------------------------------- 
             time

If I imagine pushing a book across a level table it seems like it maintains most of its speed at first but then comes to a halt very quickly (possibly because the friction causes the rate of slowdown to increase? Although the 'why' of it isn't so important here). This is a little harder to implement in pymunk, if only because there isn't a built-in method for it, but it can be done. It's not that I don't trust the chipmunk/pymunk developers, but I'm not sure if they meant for damping to simulate what I'm trying to simulate.

So, my question is not how to implement either of those curves in code, but rather - which type of curve accurately models an object sliding to a halt on a level surface?

You might think "Why is this person asking a physics question on a programming website?", but after looking at physics websites for the past four hours and getting nowhere, my hope is that, since physics modelling is common enough in programming these days, someone in the SO community might have prior knowledge about this that they can readily share.

I'm aware of this discussion on SO: how to calculate a negative acceleration? in which both types of curves are suggested, but while the asker got his question answered (someone helped him implement a Model-B type curve), the community did not come to a consensus about which is more 'physically accurate'. (I also borrowed that asker's ASCII art for one of the charts - thanks.)

I'm also aware of this example of a carrom board simulation from the pymunk showcase: https://github.com/samiranrl/Carrom_rl This also uses the built-in damping (model A, above). It seems to work fine for their purposes. But it might be that we human observers wouldn't notice if model A wasn't right since the carrom pieces are not in motion for very long. Model A looked wrong when I tried it in my sim, but then, but I am trying for much longer, slower shots, so maybe it's more noticeable there.

Or, maybe what 'seems' right to me (Model B) isn't right after all. Any thoughts are appreciated. Thanks!

2

2 Answers

2
votes

The short answer is that the deceleration is constant.

The force holding the puck to the surface is constant (because the mass is constant, and gravity is constant). That means the force of friction is constant, and therefor the deceleration is constant too.

The C demo code has an example of how to do it easily and correctly with constraints: https://github.com/slembcke/Chipmunk2D/blob/master/demo/Tank.c

2
votes

@slebcke's answer is correct, I just want to elaborate a little on the actual physics.

One simple model of friction is to say that friction is proportional to how much an object 'presses' on the surface. That is, the harder the object is pressed down, the more friction it feels. Play with your finger on the table, and you will experience the same thing.

So, how do we calculate this? I am not sure how familiar you are with vectors, so I will try to keep the formalism down. I'm going to assume the object we're looking at is only influenced by gravity.

The downwards force of the object is from Newton's law (negative because it's going 'downwards')

F_object = -m*g 

which means that the normal force (the force given by the table to the object) is

F_normal = -F_object = m*g

Now, what I said about friction before is that

F_friction = k*F_normal

where k is some constant between 0 and 1 (0 -> no friction, 1 -> maximum friction). As F_normal in our scenario is only dependant on the mass, it is constant and so the friction force is constant as well. Finally, just apply this force in the opposite direction of the velocity, and you have a simple model for how friction works!


So, my question is not how to implement either of those curves in code, but rather - which type of curve accurately models an object sliding to a halt on a level surface?

The question itself is probably a little off-topic, but the answer (for this model) is thus a linear decrease in speed (so neither your model A nor B). That is, constant fricton -> constant deceleration -> linear decrease in speed. However, from the formula

s = v*t = (v_0 + a*t)*t = v_0*t + a*t^2

we see that the breaking distance increases quadratically.