# Simple java gravity simulation

I'm trying to write a class that uses Newton's law of Gravitation to work out the field of a planet. I've tested my code by inputting values for Earth, for purely vertical motion, so I should get g = -9.8 and I don't. I have a class I can use that does every imaginable operation on vectors, called PhysicsVector. I've stared at my code for ages but can't work out what's wrong! I can add the main class if it helps, but I assume I've made some maths mistake in the GravField class here:

import java.lang.Math;
public class GravField{
public static final double G = 6.674*Math.pow(10,-11);          //Gravitational constant, same for everything
private double planetMass=0;
private double projectileX=0;
private double projectileY=0;
PhysicsVector projectilePosition = new PhysicsVector(a, projectileY);   //Haven't declared a yet, don't know if that's allowed
PhysicsVector gravityAcceleration = new PhysicsVector();

public GravField(double planetMass, double planetRadius, double projectileX, double projectileY){

double distance = Math.sqrt(projectileX*projectileX+projectileY*projectileY);   //Distance of projectile from Earth
double a = planetRadius + projectileX;              //Newton's law assumes origin at planet centre,
//my co-ord system starts at planet surface

double x = (-G*planetMass*projectileX)/(distance*distance*distance);    //Probably some maths mistake here
double y = (-G*planetMass*projectileY)/(distance*distance*distance);

gravityAcceleration.setVector(x, y);                //setVector is in PhysicsVector class and makes vector
gravityAcceleration.print2D();                  //xi + yj

}

public static double magnitude(PhysicsVector gravityAcceleration){

double magnitudeOfGravField = gravityAcceleration.magnitude();  //again magnitude is in PhysicsVector class
return magnitudeOfGravField;

}


}

• I think you are trying to simulate a flat world with the equations used for the gravital field (that is a Central field, so all the field lines start from one point). – N74 Nov 17 '15 at 15:21
• @N74 How do I account for a circular world? Never mind spherical yet! But which bit limits it to a flat world? (In the main class there is some code that means my simulation stops running after y=0, so I think I am saying it's a flat world) I don't know how to adapt it though. Different g equation? – user13948 Nov 17 '15 at 16:00
• I thought you were describing a flat world because you are adding planetRadius to projectileX. If you want a circular world forget planetRadius in GravField and work only with projectileX and projectileY. If you need a reference frame on the circle surface you need to fix its coordinates, that may be (0, planetRadius), (planetRadius, 0) or whatever (planetRadius*cos(alpha), planetRadius*sin(alpha)) you would need. Having the reference frame coordinates (we still need to fix the axis orientation), you can make a coordinates change. – N74 Nov 17 '15 at 16:18
• @ N74 Ah. Well, there's my mistake. I meant to add it to projectileY! So could I have a circular world more easily using co-ordinate axes at the centre of the circle? – user13948 Nov 17 '15 at 16:26
• Correct. In this way you enforce the circular simmetry of the problem. – N74 Nov 17 '15 at 16:28

This should be a work for codereview... but here we are, so let's continue.

These are some modifications to your class to make it better formed:

import java.lang.Math;

public class GravField {
private static final double G = 6.674*Math.pow(10,-11);           //Gravitational constant, same for everything
private double planetMass = 0;
private PhysicsVector planetPosition;

public GravField(double planetMass, double planetRadius, PhysicsVector planetPosition){
this.planetPosition = planetPosition;
this.planetMass = planetMass;
}

public PhysicsVector gravityAcceleration(PhysicsVector projectile){
PhysicsVector distanceVector = projectile.difference(this.planetPosition);  // hope your class can make vector operations
double distance = distanceVector.magnitude();   //Distance of projectile from Earth
double x;
double y;
x = (-G * this.planetMass * distanceVector.getX()) / (distance * distance * distance);
y = (-G * this.planetMass * distanceVector.getY()) / (distance * distance * distance);
} else {    // inside a planet gravity decreases linearly with the distance from the center
double magnitude = G * this.planetMass * distance/Math.pow(this.planetRadius, 3.0);
x = -magnitude * distanceVector.getX() / distance;
y = -magnitude * distanceVector.getY() / distance;
}

PhysicsVector gravity = new PhysicsVector();

gravity.setVector(x, y);                //setVector is in PhysicsVector class and makes vector

return gravity;
}

public double magnitude(PhysicsVector projectile){
double magnitudeOfGravField = this.gravityAcceleration(projectile).magnitude();  //again magnitude is in PhysicsVector class
return magnitudeOfGravField;
}
}


Now you can create your world at any position and calculate the gravity vector in every point in space, or only its magnitude.

If you had two worlds, you just need to instantiate two GravFields and you can calculate the total field on your projectile adding the fields resulting from the two worlds you instantiated.

Enjoy!

• Oh, that is so neat! You're a hero, thank you! – user13948 Nov 17 '15 at 18:57

Newton's law of gravity (divided by the mass of the projectile) is

$g = \frac{G m_e \vec{r}}{r^3}$

Hand calculating this for Earth's mass and radius gives a value of $9.93\ m/s^2$ which is close enough for my tastes (I expect error since we are so close to the surface and Earth isn't a point mass).

Your error is that you are using $\vec{r}$ in coordinates that have an origin at the surface rather than at the center of the earth. You need:

double x = (-G*planetMass*a)/(distance*distance*distance);

• The equations seem correct as OP is evaluating the components of $g = \frac{G m_e}{r^3}\vec{r}$. – N74 Nov 17 '15 at 15:08
• @N74 you are correct, it was actually a coordinate system problem (error in the $\vec{r}$ rather than the division. I have updated the answer. – Godric Seer Nov 17 '15 at 15:12
• The problem is that planetRadius has to be projected both on the x and on the y axis – N74 Nov 17 '15 at 15:15
• @Godric Seer Oh, right! I thought only y had to have the planet radius added. Because I put my co-ordinate axes on the surface of the planet? Oh, and also my code stops running when y=0, there's a bit in the main class to do that, which I think is why x doesn't need the radius added? – user13948 Nov 17 '15 at 15:57