2011-08-10 53 views
8

我想模拟自由落体和与地面的碰撞(例如弹跳球)。物体会落入真空中 - 可以省略空气阻力。与地面的碰撞会导致一些能量损失,最终物体会停止移动。我使用JOGL渲染一个点,这是我的下降对象。重力恒定(-9.8 m/s^2)。重力模拟

我发现了一个欧拉法计算该点的新位置:

deltaTime = currentTime - previousTime; 
vel += acc * deltaTime; 
pos += vel * deltaTime; 

,但我做错了什么。点反弹几次,然后它下移(非常慢)。

这里是一个伪代码(初始POS =(0.0F,2.0F,0.0F),初始电平(0.0F,0.0F,0.0F),比重= -9.8f):

display() 
{ 
    calculateDeltaTime(); 
    velocity.y += gravity * deltaTime; 
    pos.y += velocity.y * deltaTime; 

    if(pos.y < -2.0f) //a collision with the ground 
    { 
     velocity.y = velocity.y * energyLoss * -1.0f; 
    } 

} 

达到现实效果的最佳方式是什么?欧拉方法如何引用恒定加速度方程?

+0

如果您仅将能量损失排除在等式之外,会发生什么情况? – redbmk

+0

除了Yochai的回答,你可以考虑在你的碰撞情况下将'pos.y'设置为地平面以避免削波错误 –

+0

如果没有能量损失,该点也会在一段时间后停止反弹,并且它非常缓慢地向下移动。 – Vert

回答

6

由于浮点不会很好地凑合,所以你永远不会得到实际为0的速度。你可能会得到类似-0.00000000000001之类的东西。

当距离足够近时,您需要将其设置为0.0。 (定义一些三角洲。)

2

要扩大我上面的评论,并回答Tobias,我会在这里添加一个完整的答案。

经过初步检查,我确定你正在流血速度快。简单地说,动能和速度之间的关系是E = m v^2 /2,因此服用导数相对于速度后,你会得到

delta_E = m v delta_v 

然后,根据energyloss是如何定义的,你可以建立delta_Eenergyloss之间的关系。例如,在大多数情况下energyloss = delta_E/E_initial,则上述关系可以简化为

delta_v = energyloss*v_initial/2 

这是假设的时间间隔小,让您与v_initial取代v第一方程式中,所以你应该能够为了你的行为而放弃它。清楚起见,delta_v从您的碰撞区域内的velocity.y中减去,而不是您所拥有的。

至于增加空气阻力与否的问题,答案取决于。对于较小的初始下降高度,这并不重要,但由于反弹和较高的下降点,能量损失较小。对于1克,1英寸(2.54cm)直径的,光滑球,我绘制有和没有空气摩擦与下落高度之间的时间差:

difference in time with and without air-drag vs. drop height

对于低能量损失的材料(80 - 90 + %的能量保留),我会考虑将它添加到10米和更高的高度。但是,如果水滴不到2-3米,我就不会打扰。

如果有人想要计算,我会分享它们。

+0

+1谢谢你的回答。我认为这也是一个很好的解决方案。与Vert的原始碰撞实施形成对比的是,您的身体与地面碰撞并在那里休息(比如枕头)可能会产生“较软”的碰撞,而Vert的版本则是有损反弹。当然选择哪一个取决于所需的物理行为。你说得对,包括空气摩擦会是过度的。 –

+0

@Tobias,这也是一个有损的反弹,只是稍微软一点的反弹。 – rcollyer

+0

@Vert,当我发布它时我从未注意到,但是我从'delta_v'的结果中删除了'energyloss'。现在已经修复了。 – rcollyer