tubberd
tubberd

Reputation: 540

Implementing Newton's law of universal gravity in C#

Im trying to create a (poor) simulation of the movement of planets, using newtons law of universal gravity to calculate the velocities and then adding all of them together to calculate the final movement direction. however, when trying to implement the formula, my planets just dont move and when outputting the calculated velocity float on the console, it says +infinity. heres the algorithm i use:

    private void calculateVelocity()
            {
                List<Vector2> Velocities = new List<Vector2>();
                foreach (Planet p in Game1.Planets)
                {
                   
                    
                    Vector2 dir = Vector2.Subtract(p.Position, p.Position);
                    float radius = dir.Length();
                    float power = G * ((Mass * p.Mass) / radius);
                    float acceleration = power / Mass;
                    float velocity = acceleration * deltaTime * 0.1f;
                    //Console.WriteLine(velocity) -- Outputs random numbers and often +infinity !!!
                    dir.Normalize();
                    dir = Vector2.Multiply(Position, velocity);
                    Velocities.Add(dir);
                    
                }
                foreach (Vector2 v in Velocities)
                {
                    Vector2.Add(Velocity, v);
                }
            }

i hope u can help me solve this problem. thx in advance, Daniel

EDIT

Heres the (hopefully) working version of this, in case anyone needs this.

private void calculateVelocity()
            {
                List<Vector2> Velocities = new List<Vector2>();
                foreach (Planet p in Game1.Planets)
                {
                    if(p.Identifier != this.Identifier)
                    {
                    Vector2 dir = Vector2.Subtract(p.Position, Position);
                    float radius = dir.Length();
                    float force = G * ((Mass * p.Mass) / ((float)Math.Pow(radius,2));
                    float acceleration = force / Mass;
                    float velocity = acceleration * deltaTime * 0.1f;
                    //Console.WriteLine(velocity) -- Outputs random numbers and often +infinity !!!
                    dir.Normalize();
                    dir = Vector2.Multiply(dir, velocity);
                    Velocities.Add(dir);
                    }
                }
                foreach (Vector2 v in Velocities)
                {
                    Vector2.Add(Velocity, v);
                }
            }

Upvotes: 3

Views: 3326

Answers (3)

Michael McGuire
Michael McGuire

Reputation: 1034

You probably need to skip the current planet. You need to test inside the foreach loop to skip this in the calculations. Otherwise, dir will be the zero vector. Then radius will be 0.

Also, you are confusing power and force. Those are very distinct concepts in physics. For everyone, please change that.

Also,

float power = G * ((Mass * p.Mass) / radius);

Should be:

float force = G * ((Mass * p.Mass) / radius / radius);

Since gravity falls off inversely proportional to the square of the distance.

Then you:

dir.Normalize();
dir = Vector2.Multiply(Position, velocity); // This overwrites dir... why normalize it first?

I am guessing you meant:

dir.Normalize();
dir = Vector2.Multiply(dir, velocity);

These should get you up and running.

Upvotes: 2

Daniel Alves
Daniel Alves

Reputation: 48

You could be getting an infinity value on a float when a divide by zero occurs.. Check to see if either radius or Mass has a 0 value first...

Upvotes: 1

Nico Schertler
Nico Schertler

Reputation: 32587

You have a zero-length direction:

Vector2 dir = Vector2.Subtract(p.Position, p.Position);

should probably be

Vector2 dir = Vector2.Subtract(p.Position, Position);

or just

Vector2 dir = p.Position - Position;

Upvotes: 5

Related Questions