使用Box2D模拟“牛顿万有引力定律”

时间:2011-07-20 06:52:24

标签: physics simulation box2d gravity

我想使用Box2D模拟Newton's law of universal gravitation

我查看了手册,但找不到办法。

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

任何提示?

3 个答案:

答案 0 :(得分: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 );
    }
}

答案 1 :(得分:1)

不幸的是,Box2D没有原生支持,但您可以自己实现:Box2D and radial gravity code

答案 2 :(得分: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,然后在每个步骤的每个对象之前进行计算,但这可能没有那么大的性能。

相关问题