Simulate “Newton's law of universal gravitation” using Box2D

前端 未结 3 782
一向
一向 2020-12-28 10:28

I want to simulate Newton\'s law of universal gravitation using Box2D.

I went through the manual but couldn\'t find a way to do this.

Basically what I want t

相关标签:
3条回答
  • 2020-12-28 10:43

    Unfortunately, Box2D doesn't have native support for it, but you can implement it yourself: Box2D and radial gravity code

    0 讨论(0)
  • 2020-12-28 10:47

    As said by others, Box2D has no buildin support for it. But you can add support for it to the library in 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. 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.

    The 10.0f are just an approximation of the 9.81f from earth, you might need to adjust it. 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.

    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)
  • 2020-12-28 11:02

    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 );
        }
    }
    
    0 讨论(0)
提交回复
热议问题