Star.java
// Star: Simulate N-body problem
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
public class Star extends Applet implements ActionListener{
Stars S = new Stars(); // instantiate an entire system
Body b; // a single body for storing return values
Button Go;
TextField IncrRep, DispRep;
Label IncrRepL, DispRepL;
TextField View, Delta;
Label ViewL, DeltaL;
int dispRep = 0, maxDispRep = 200; // # of points to display
int incrRep = 500;
int view = 0; // 0: xy-plane, 1: xz-plane, 2: yz-plane
double d = 0.001;
double scale = 5.0; // was 3.0
int starN = 0; // current number of stars
int x_old[] = new int[6]; // used to hold old coords so that one
int y_old[] = new int[6]; // can draw a line
public void init() {
// perfectly stable
//S.newStar( 1.0, 0.0, 0.0, 0.0, 0.6, 0.0, .5);
//S.newStar(-1.0, 0.0, 0.0, 0.0, -0.32, 0.0, 1.0);
//S.newStar( 1.2, 0.0, 0.0, 0.0, 1.8, 0.0, 0.000005);
S.newStar( 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 1.0);
S.newStar(-1.0, 0.0, 0.0, 0.0, -0.5, 0.0, 1.0);
S.newStar( 0.0, 1.75, 0.0, -0.862, 0.0, 0.0, 0.000005);
starN = S.getNum();
Go = new Button("Go");
Go.addActionListener(this);
add(Go);
IncrRep = new TextField(10); DispRep = new TextField(5);
IncrRep.addActionListener(this); DispRep.addActionListener(this);
IncrRepL = new Label("# increments");
DispRepL = new Label("# points displayed");
add(IncrRepL); add(IncrRep); add(DispRepL); add(DispRep);
View=new TextField(2); Delta=new TextField(8);
View.addActionListener(this);Delta.addActionListener(this);
ViewL = new Label("Views"); DeltaL = new Label("Delta");
add(ViewL); add(View); add(DeltaL); add(Delta);
}
private void plotPt(Graphics g, double x, double y, double z,
int num, double sc, int pix) {
double xv = x, yv = y; // local x and y coords
int xd, yd; // scaled x and y coords
if (view == 1) {yv = z;}
else if (view == 2) {xv = y; yv = z;}
xd = (int)((pix/2)*(xv/sc + 1.0));
yd = (int)((pix/2)*(yv/sc + 1.0));
if (num == 0) g.setColor(new Color(255, 0, 0));
else if (num == 1) g.setColor(new Color(0, 255, 0));
else if (num == 2) g.setColor(new Color(0, 0, 255));
g.fillOval(xd, yd, 4, 4);
}
private void plotLine(Graphics g, double x, double y, double z,
int num, double sc, int pix) {
double xv = x, yv = y; // local x and y coords
int xd, yd; // scaled x and y coords
if (view == 1) {yv = z;}
else if (view == 2) {xv = y; yv = z;}
xd = (int)((pix/2)*(xv/sc + 1.0));
yd = (int)((pix/2)*(yv/sc + 1.0));
if (x_old[num] == 0 && y_old[num] == 0) {
x_old[num] = xd; y_old[num] = yd;
}
if (num == 0) g.setColor(new Color(255, 0, 0));
else if (num == 1) g.setColor(new Color(0, 255, 0));
else if (num == 2) g.setColor(new Color(0, 0, 255));
g.drawLine(x_old[num], y_old[num], xd, yd);
x_old[num] = xd; y_old[num] = yd;
}
public void paint(Graphics g) {
Body b;
// showStatus("* 3");
setBackground(Color.darkGray);
while (dispRep < maxDispRep) {
S.increment(incrRep); dispRep++;
for (int i = 0; i < starN; i++) {
b = S.getLocation(i);
plotLine(g, b.x, b.y, b.z, i, scale, 600);
}
}
dispRep = 0;
} // paint
public void actionPerformed (ActionEvent e) {
if (e.getSource() == Go) {
repaint();
} else if (e.getSource() == IncrRep) {
incrRep = Integer.parseInt(e.getActionCommand());
} else if (e.getSource() == DispRep) {
maxDispRep = Integer.parseInt(e.getActionCommand());
} else if (e.getSource() == View) {
view = Integer.parseInt(e.getActionCommand());
S.setView(view);
} else if (e.getSource() == Delta) {
d = Double.valueOf(e.getActionCommand()).doubleValue();
S.setDelta(d);
}
}
public void update(Graphics g) { // prevent background clearing
paint(g);
}
}
Stars.java
// Stars.java: a system of N bodies in space
public class Stars {
private Body sys[] = new Body[6]; // the entire system
private int view = 0; // 0: xy-plane, 1: xz-plane, 2: yz-plane
private double delta = 0.00001; // amount of change in each increment
private int starN; // number of stars
public void setView(int v) {
view = v;
}
public void setDelta(double d) {
delta = d;
}
public int getNum() {
return starN;
}
public Body getLocation(int starNum) {
return sys[starNum];
}
public void newStar(double xc, double yc, double zc,
double vxc, double vyc, double vzc, double mc) {
sys[starN] = new Body(xc, yc, zc, vxc, vyc, vzc, mc);
starN++;
}
public void increment(int incrRep) {
double rx, ry, rz; // vector from jth to ith object
double ax, ay, az; // acceleration jth experiences
double f; // force on jth (scalar)
double fx, fy, fz; // components of force on jth
double r; // distance from ith to jth object
double G = 1.0; // universal gravitation constant
int n = starN;
for (int dum = 0; dum < incrRep; dum++) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (i != j) {
// here we calculate and apply the influence
// of the ith object on the velocity and position
// of the jth
rx = sys[i].x - sys[j].x;
ry = sys[i].y - sys[j].y;
rz = sys[i].z - sys[j].z;
r = Math.sqrt(rx*rx + ry*ry + rz*rz);
f = G * sys[i].m * sys[j].m /(r*r);
fx = f * rx / r;
fy = f * ry / r;
fz = f * rz / r;
ax = fx / sys[j].m;
ay = fy / sys[j].m;
az = fz / sys[j].m;
sys[j].vx += ax * delta;
sys[j].vy += ay * delta;
sys[j].vz += az * delta;
}
for (int i = 0; i < n; i++) {
sys[i].x += sys[i].vx * delta;
sys[i].y += sys[i].vy * delta;
sys[i].z += sys[i].vz * delta;
}
} // for (int dum ...
} // increment
}