- Home /
Point gravity implementation lacks precision
Hello
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);
Fg_dir.Normalize();
//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 :(
I turned off default engine gravity in rigidbodies. There is also no drag.
Answer by Bunny83 · Nov 11, 2011 at 12:26 PM
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.
Answer by kubanvip · Nov 11, 2011 at 01:10 PM
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:
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.
EDIT:
I have done it. Changing velocity instead of constant force, works great.
Your answer
Follow this Question
Related Questions
calculate the future position of an object in orbit 1 Answer
Tornado throwing back force after pulling 1 Answer
How do you create a continuous physics simulation in Unity? 1 Answer
Natural rotation of orbiting object 3 Answers
Artificial Gravity 2 Answers