Point gravity implementation lacks precision


I wrote my own gravity implementation to simulate some space behaviors, like Earth orbiting the Sun. The problem is I don’t know why it’s not precise.

Here is the most important code part (runs in fixed update):

            //Gravitational force direction
            Vector3 Fg_dir = oSource.transform.position - oAffected.transform.position;
            float distance = Fg_dir.magnitude;

            //Computing scalar value of gravitational force
            float GMmR2 = (GConstant * oSource.Mass * oAffected.Mass) / (distance * distance);


            //Aplying force by using Constant force component
            oAffected.constantForce.force =
                new Vector3(GMmR2 * Fg_dir.x, GMmR2 * Fg_dir.y, GMmR2 * Fg_dir.z);

As you can see, it’s only gravitational force equation implementation.

I decided to run simple simulation:

Gravitational constant = 150f

gameobject A:
postion: {0; 0; 0}
mass: 100

gameobject B:
position: {30; 0; 0}
mass: 1
initial velocity: {0; 0; 22.36068f}

Initial velocity was computed from equation: Fg = Fc

Fg = Gravitational force

Fc = Centrifugal force

GMm/r^2 = mV^2/r

GM/r = V^2

V = sqrt( GM/r )

V = sqrt( 150f * 100f / 30f )

V = 22.36068f

Looks good, but after one orbit object B is at {35; 0; 0}.
After two orbits it is {40; 0; 0}
After three {45; 0; 0} and so on…

There is something wrong but I don’t know where :frowning:

I turned off default engine gravity in rigidbodies. There is also no drag.

Do you use the real-world values (G constant, mass, distance, diameter)? Because you will get very very much jitter due to float precision. You can try to switch to double where it’s possible, but Unity works with floats in the end. It might help to eleminate some computation errors, but the general problem remains.

When you say (35; 0; 0) and (40; 0; 0) are that Unity-units (aka meters)? Because you have to be careful at extreme-low orbit / high-speed simulations. Real-world gravity is not “calculated” at specific rate (like in simulations). The actual velocity vector changes unlimited times a sec. That’s the real world. If you have a low orbit and a high speed object there always will be an error because you calculate the forces at certain time steps.

If you don’t have that heavy physics-based things in your scene you can increase the physics-framerate to 1000fps or more to get a better result.

You are right ! :)

I fixed physics-framerate to 1000fps and now the error is 0.25 meter per orbit (previously it was 5 meter per orbit).

I known about float precision, that's why I used small numbers, but I forgot about physics fixed timestep.

So I suppose that if I want to keep full precision I have to change things to work like this:

alt text

In above picture, if object is orbiting sth in 6 second, that's how it has to move if physics framerate is set to 1 second. If we set timestep to 0.5 second there would be 12 linear moves and so on.


I have done it. Changing velocity instead of constant force, works great.