2

我的物理引擎中有一个碰撞解决方法,如下所示:

Vector2 n1pos = n1.NonLinearSpace != null ? n1.NonLinearPosition : n1.Position;
Vector2 n2pos = n2.NonLinearSpace != null ? n2.NonLinearPosition : n2.Position;
Vector2 posDiff = n2pos - n1pos;
Vector2 posDiffNormal = posDiff;
posDiffNormal.Normalize();
float totalRadius = n1.Radius + n2.Radius;
float posDiffLength = posDiff.Length();
float interPenetration = totalRadius - posDiffLength;
float averageRestitution = (n1.RestitutionCoefficient + n2.RestitutionCoefficient) / 2;

Vector2 forceAmount = Vector2.Multiply(posDiffNormal, interPenetration);
Vector2 n1force =
    (
        (n1.Velocity * n1.Mass) +
        (n2.Velocity * n2.Mass) +
        n2.Mass * averageRestitution * (n2.Velocity - n1.Velocity)
    ) /
    (n1.Mass + n2.Mass);
Vector2 n2force =
    (
        (n1.Velocity * n1.Mass) +
        (n2.Velocity * n2.Mass) +
        n1.Mass * averageRestitution * (n2.Velocity - n1.Velocity)
    ) /
    (n1.Mass + n2.Mass);
n1.ApplyForce(???);
if (!n1.IsStatic)
{
    n1.Position += ???;
}
n2.ApplyForce(???);
if (!n2.IsStatic)
{
    n2.Position += ???;
}

现在,我无法弄清楚在我的引擎中应用什么来获得适当的恢复系数。(???部分)。有人可以帮忙吗?

4

2 回答 2

6

从这个和你的其他问题来看,你试图在你能走路之前跑。

  1. 你试图一次编写几个不熟悉的东西,而你应该一次处理一个。尝试将恢复系数设置为 0,这样您的对象就会像油灰块一样。这将更容易编码,一旦你开始工作,你就可以尝试弹性碰撞。
  2. 无意冒犯,但在没有学习基础物理的情况下尝试编写物理引擎只是自虐。您可以坐下来阅读教科书或进行实验,但如果不了解其部件,就无法让引擎正常工作。
于 2009-11-05T22:30:38.940 回答
5

我意识到这是一个老问题,但我遇到了同样的问题,谷歌打开了这个页面。我想我可能会分享我的发现。首先,您必须意识到恢复系数是碰撞的属性,而不是碰撞中涉及的任何物体的属性。也就是说,对于 n 个对象,您需要定义 n(n-1)/2 个恢复系数(每对物体一个)。

但是,我研究过的物理引擎(Bullet、Chipmunk 和 Box2d)都将恢复原状定义为物体的属性。在碰撞发生时,它们将两个物体的恢复系数组合成一个值,并在碰撞解决方案中使用该值。显然,这在物理上是不正确的。但这对游戏来说并不重要:它只需要以直观的方式表现即可。以下是这些物理引擎使用的恢复功能:

  • 子弹:restitution = body1->restitution * body2->restitution
  • 花栗鼠:restitution = body1->restitution * body2->restitution
  • 方框2d:restitution = max(body1->restitution, body2->restitution)

Box2d 允许用户在配置文件中自定义恢复功能。子弹和花栗鼠没有。

我建议您选择任何感觉最好的恢复混合功能。稍微玩一下,看看你喜欢什么。

于 2010-07-25T05:42:01.193 回答