9

我想使用 Box2D模拟牛顿万有引力定律。

我浏览了手册,但找不到这样做的方法。

基本上我想要做的是在空间中放置几个​​物体(零重力)并模拟运动。

有小费吗?

4

3 回答 3

18

这很容易实现:

for ( int i = 0; i < numBodies; i++ ) {

    b2Body* bi = bodies[i];
    b2Vec2 pi = bi->GetWorldCenter();
    float mi = bi->GetMass();

    for ( int k = i; k < numBodies; k++ ) {

        b2Body* bk = bodies[k];
        b2Vec2 pk = bk->GetWorldCenter();
        float mk = bk->GetMass();

        b2Vec2 delta = pk - pi;
        float r = delta.Length();
        float force = G * mi * mk / (r*r);

        delta.Normalize();
        bi->ApplyForce(  force * delta, pi );
        bk->ApplyForce( -force * delta, pk );
    }
}
于 2011-07-20T17:47:07.687 回答
1

不幸的是,Box2D 没有对它的原生支持,但您可以自己实现它:Box2D 和径向重力代码

于 2011-07-20T06:59:34.967 回答
1

正如其他人所说,Box2D 没有内置支持。但是您可以在 b2_islands.cpp 的库中添加对它的支持。只需更换

v += h * b->m_invMass * (b->m_gravityScale * b->m_mass * gravity + b->m_force);  

int planet_x = 0;
int planet_y = 0;
b2Vec2 gravityVector = (b2Vec2(planet_x, planet_y) - b->GetPosition());    
gravityVector.Normalize();    
gravityVector.x = gravityVector.x * 10.0f;    
gravityVector.y = gravityVector.y * 10.0f;    
v += h * b->m_invMass * (b->m_gravityScale * b->m_mass * gravityVector + b->m_force);    

如果你只有一个星球,那是一个简单的解决方案。如果您想要越远的力量越小,您可以使用 1/gravityVector 而不是对其进行归一化。这也使得增加行星的引力成为可能。您还可以遍历行星列表并将重力向量相加。

另外实现一个像 b2World::CreatePlanet 这样的函数可能会很有用。

10.0f 只是来自地球的 9.81f 的近似值,您可能需要对其进行调整。如果行星的质量相关,您可能需要乘以一个常数,使其看起来更逼真,或者只是增加物体的密度以使其与行星的真实重量相匹配。

当然,您也可以将重力设置为 0、0,然后在每个对象的每一步之前计算它,但这可能没有那么多性能。

于 2020-08-25T13:21:09.650 回答