简体   繁体   English

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

[英]Simulate "Newton's law of universal gravitation" using Box2D

I want to simulate Newton's law of universal gravitation using Box2D.我想使用 Box2D 模拟牛顿万有引力定律

I went through the manual but couldn't find a way to do this.我浏览了手册,但找不到这样做的方法。

Basically what I want to do is place several objects in space (zero gravity) and simulate the movement.基本上我想要做的是在空间中放置几个物体(零重力)并模拟运动。

Any tips?有小费吗?

It's pretty easy to implement:这很容易实现:

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 );
    }
}

As said by others, Box2D has no buildin support for it.正如其他人所说,Box2D 没有内置支持。 But you can add support for it to the library in b2_islands.cpp.但是您可以在 b2_islands.cpp 的库中添加对它的支持。 Just replace只需更换

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

with

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);    

Thats a simple solution if you have only one planet.如果你只有一个星球,那是一个简单的解决方案。 If you want less force the further away you are, you could use 1/gravityVector instead of normalizing it.如果您想要越远的力量越小,您可以使用 1/gravityVector 而不是对其进行归一化。 That would also make it possible to add up the gravity of to planets.这也使得增加行星的引力成为可能。 The you could also iterate over a planet list and sum the gravityVectors up.您还可以遍历行星列表并将重力向量相加。

Additionally implementing a function like b2World::CreatePlanet might be usefull then.此外,实现像 b2World::CreatePlanet 这样的 function 可能会很有用。

The 10.0f are just an approximation of the 9.81f from earth, you might need to adjust it. 10.0f 只是来自地球的 9.81f 的近似值,您可能需要对其进行调整。 If the mass of the planet is relevant you might need a constant to be multiplied with it, to make it look more realistic, or just increase the density of the object to make it match the real weight of a planet.如果行星的质量相关,您可能需要乘以一个常数,使其看起来更逼真,或者只是增加 object 的密度以使其与行星的实际重量相匹配。

Sure you can also set the gravity to 0, 0 and then calculate it before each step for every object, but that might not have so much performance.当然,您也可以将重力设置为 0、0,然后在每个 object 的每一步之前计算它,但这可能没有那么多性能。

Unfortunately, Box2D doesn't have native support for it, but you can implement it yourself: Box2D and radial gravity code不幸的是,Box2D 没有对它的原生支持,但您可以自己实现它: Box2D 和径向重力代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM