How can I simulate the gravity of a sphere instead of a plane?

For a naval warfare game, I wish to implement a surface that simulates a curved plane with horizon. The plane is rendered with water physics, which needs, along with all physical objects, avatars and projectiles, to respond to gravity as a focal point rather than a distributed surface.

  • 5
    \$\begingroup\$ To answer this question we would need to know how you are simulating gravity right now and why this system can not be easily generalized to a vector facing a point instead of one facing straight down. \$\endgroup\$
    – Philipp
    May 11 '15 at 14:24
  • 3
    \$\begingroup\$ Also, how familiar are you with vector math in general? \$\endgroup\$
    – Philipp
    May 11 '15 at 14:26
  • \$\begingroup\$ The title says "sphere", but the body says "a curved plane". Which do you mean? \$\endgroup\$
    – Anko
    May 16 '15 at 8:52

It depends on the effect you are looking for.

If you are looking for a constant gravity the answer is:

object.AddForce(((Vector) sphere.center - (Vector) object.pos).normalized * gravityForce);

If you are looking for a gravity based on the distance between the object and the sphere then you replace gravityForce with this formula:

gravityForce =  6.673×10^(−11) * sphere.mass * object.mass / Distance(sphere.center, object.pos); 
  • 3
    \$\begingroup\$ If you go with the second route, masses must be in kilograms. \$\endgroup\$ May 11 '15 at 20:27
  • 1
    \$\begingroup\$ @El'endiaStarman It's worth noting that the gravitational constant (6.673×10^(−11) in the above) can be adjusted for other units of mass. \$\endgroup\$
    – chbaker0
    May 11 '15 at 20:50

You simply need a reworked Newton's law of universal gravitation.

So F=G(M1*M2)/R2 translates as code into.

// Create force scalar based off of distance.

distanceSquared = (gravityCenter.y - object.y)^2 + (gravityCenter.x - object.x)^2

force = gravitationalConstant*distanceSquared

// Get direction from object to gravity epicenter.

direction = arctangent2(gravityCenter.y - object.y, gravityCenter.x - object.x)

// Transform vector into into coordinate based impulse.

object.xVelocity += force*cosine(direction)
object.yVelocity += force*sine(direction)

Then adjust gravitationalConstant to suit.

NOTE: Unless you want to send ships into space, implementing gravity based on distance is completely a waste of cycles as a constant "downwards" force is more processor friendly.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.