I am designing a planetary system simulator. The coordinates used are standard for JPanel (0,0 in the upper left corner).
My model is based on a class Body:
public class Body {
private double x, y; // position
private double w, h; // dimensions for drawing
private double vx = 0, vy = 0; // velocities along x, y axes
private double ax = 0, ay = 0; // accelerations along x, y axes
private double mass = 1; // default = 1
private boolean stationary = false; // stationary body is centered during simulation
/* ... not showing all the setters and getters */
Because the force of gravity is the same for any two interacting bodies, I designed the methods to take another body as an argument, so we can call planet1.interact(planet2)
Distance calculation:
public double calculateDistX(Body other) {
double x1 = this.getX();
double x2 = other.getX();
return Math.sqrt(Math.pow(x2 - x1, 2));
}
public double calculateDistY(Body other) {
double y1 = this.getY();
double y2 = other.getY();
return Math.sqrt(Math.pow(y2 - y1, 2));
}
public static double calculateDistance(double dist_x, double dist_y) {
return Math.sqrt(Math.pow(dist_x, 2) + Math.pow(dist_y, 2));
}
Finally, the method that calculates gravitational force:
public void interact(Body other) {
double x = calculateDistX(other);
double y = calculateDistY(other);
double r = calculateDistance(x, y);
double force = (this.getMass() * other.getMass()) / Math.pow(r, 2);
double force_x = force * (x / r); // force * cos
double force_y = force * (y / r); // force * sin
/* calculate accelerations for both bodies, set vector orientation */
if (other.getX() > this.getX()) {
this.setAx(force_x / this.getMass());
other.setAx(-force_x / other.getMass());
} else {
this.setAx(-force_x / this.getMass());
other.setAx(force_x / other.getMass());
}
if (other.getY() > this.getY()) {
this.setAy(force_y / this.getMass());
other.setAy(-force_y / other.getMass());
} else {
this.setAy(-force_y / this.getMass());
other.setAy(force_y / other.getMass());
}
/* calculate velocities for both bodies */
this.setVx(this.getVx() + this.getAx());
this.setVy(this.getVy() + this.getAy());
other.setVx(other.getVx() + other.getAx());
other.setVy(other.getVy() + other.getAy());
/* calculate positions for both bodies */
this.setX(this.getX() + this.getVx());
this.setY(this.getY() + this.getVy());
other.setX(other.getX() + other.getVx());
other.setY(other.getY() + other.getVy());
}
I don't really know how good/bad this model is. The section in interact
that sets the vector orientation looks like it can be simpler, but I can't figure it out.
Also, I have doubts about this method, because calling:
planet1.interact(planet2);
planet1.interact(planet3);
planet2.interact(planet3);
Makes planet2
and planet3
interact AFTER the original position of planet1
and planet2
has changed, and it's not how it's hapenning in reality. I don't know how important that would be, though.
interact(Body)
method and passing time to the method somehow? Right now, I have aTimer
in my drawing method that calls theinteract(Body)
for every Body each time. \$\endgroup\$