我在边缘形状上有一个盒子形状。现在我在盒子上施加脉冲,让它可以跳跃。但是当它落地时,它应该不会再移动了。所以我将盒子的恢复设置为0。并且边形和盒形的摩擦力为1。但在地面上很容易滑动。如何防止任何滑动?

最佳答案

正如您所发现的,您可以通过增加足够高的摩擦力来防止滑动。

至于您可以将摩擦设置为的最大值是多少,没有记录摩擦值的最大值。也就是说,最大摩擦值有一些限制。

尝试将 std::numeric_limits<float>::infinity() 作为 VaryingFriction 测试平台测试中的第一个摩擦值,导致无限摩擦立方体撞击的第一个平台消失。哎呀!不是我想要的结果。

Box2D 2.3.2 C++ source code 的回顾揭示了与摩擦相关的变量,例如:

  • m_frictionb2Fixture 成员变量。
  • m_frictionb2Contact 成员变量。
  • frictionb2ContactVelocityConstraint 成员变量。

  • 这些被定义为 float32 类型的实例,而 float 类型又是 m_friction - a single precision floating-point type 。这为我们提供了以下内容的最大上限(无溢出):
    std::numeric_limits<float>::max()
    

    然而,b2Contactm_friction 成员变量本质上是取夹具摩擦乘积的平方根的结果:
    std::sqrtf(m_fixtureA->m_friction * m_fixtureB->m_friction)
    

    因此,任何给定夹具的 b2Fixture 值都需要低于 float-max 的平方根,以避免该产品中潜在的溢出。即,对于任何 friction 的摩擦设置,我们得到了一个更现实的上限:
    std::sqrtf(std::numeric_limits<float>::max())
    

    如果不是因为 b2ContactVelocityConstraintb2ContactSolver::SolveVelocityConstraints() 成员变量发生了什么,那可能就足够了;它乘以(在 normalImpulse 中)另一个浮点数 - 每个速度约束点的 ojit_code 。所以 float-max 的平方根可能仍然太高,无法确保避免任何潜在的溢出。

    溢出可能意味着使用无穷大进行摩擦会发生什么:哎呀!虽然由于使用太高的摩擦值而导致物体消失很可能是一个错误,但没有修复库的源代码,我认为我们有点卡住了最大浮点值的平方根作为上限仍然有风险。顺便说一句,我提交了一个关于此问题的 issue 以及我找到的解决方法。

    根据经验,我会增加固定装置的摩擦力,直到不再滑动,然后就让它留在那里。

    OTOH,还有其他防止滑动的方法(除了增加摩擦力),例如……
  • 改变 body 的类型。如果在与地面碰撞后将 body 设置为静态,则它根本不会物理移动。直到你把它改回动态。
  • 当盒子与地面碰撞时创建一个关节,将盒子绑定(bind)到地面。
  • 10-07 20:40