3

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!

4

2 回答 2

2

@slebcke 的回答是正确的,我只是想详细说明一下实际的物理学。

一种简单的摩擦模型是说摩擦与物体“压”在表面上的程度成正比。也就是说,物体被压得越重,感觉的摩擦力就越大。用你的手指在桌子上玩,你会体验到同样的事情。

那么,我们如何计算呢?我不确定你对向量有多熟悉,所以我会尽量减少形式主义。我将假设我们正在查看的对象仅受重力影响。

物体的向下力来自牛顿定律(负数,因为它“向下”)

F_object = -m*g 

这意味着法向力(表给对象的力)是

F_normal = -F_object = m*g

现在,我之前所说的摩擦是

F_friction = k*F_normal

其中 k 是介于 0 和 1 之间的某个常数(0 -> 无摩擦,1 -> 最大摩擦)。由于F_normal在我们的场景中仅取决于质量,它是恒定的,因此摩擦力也是恒定的。最后,只需将这个力施加在与速度相反的方向上,你就有了一个摩擦如何工作的简单模型!


所以,我的问题不是如何在代码中实现这些曲线,而是 - 哪种类型的曲线可以准确地模拟在水平面上滑动到停止的对象?

这个问题本身可能有点离题,但答案(对于这个模型)因此是速度的线性下降(所以你的模型 A 和 B 都不是)。也就是说,恒定摩擦 -> 恒定减速度 -> 速度线性下降。然而,从公式

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

我们看到断裂距离呈二次方增加。

于 2017-03-01T08:43:45.610 回答
2

简短的回答是减速是恒定的。

将冰球保持在表面上的力是恒定的(因为质量是恒定的,而重力是恒定的)。这意味着摩擦力是恒定的,因此减速度也是恒定的。

C 演示代码有一个示例,说明如何使用约束轻松正确地执行此操作:https ://github.com/slembcke/Chipmunk2D/blob/master/demo/Tank.c

于 2017-02-28T23:45:50.720 回答