[an error occurred while processing this directive]

Checklist: N-Body Simulation


Frequently Asked Questions

What preparation do I need before beginning this assignment? Read Sections 1.4 and 1.5 of the textbook.

Any advice on completing this programming assignment? Warning: this program is more involved than the previous ones, and you should budget more time accordingly. The best advice we can give you is to carefully test, debug, and re-test your code as you write it. Do not attempt to write the whole program at once—if you do, then you will have no idea where to find the error if the program doesn't work. Proactive testing will save you enormous amounts of time in the long run. Trust us! Also, come to TA office hours early and often! You can always attend any TA's office hours.

Can I work in a group on this assignment? You must write your own Java code, as per the homework policy. But we encourage you to discuss the assignment with each other before starting to program it. In particular, working with other students to carefully translate the figures in the assignment into the necessary formulas for updating position and velocity is likely to be very helpful. Remember to not everyone you work with in your readme.txt.

DrJava doesn't let me redirect standard input. What should I do instead? Use the command line, as described in lecture. Here are instructions for configuring your system to use the command line: [ Windows · Mac · Linux ]

Do I have to follow the assignment specifications for reading input from the command line and standard input, and writing output to standard drawing and standard output? Yes, or you will lose a substantial number of points.

Where can I find the APIs for StdIn, StdOut, StdDraw, and StdAudio? They are on p. 716–718 of the textbook. They are also available online in this Java cheatsheet.

How do I plot a picture using StdDraw? The command StdDraw.picture(x, y, filename) plots the image in the given filename (either JPEG, GIF, or PNG format) on the canvas, centered on (x, y).

I'm not a physicist/mathemetician, and I have a hard time understanding the formulas. The secret is that you don't have to understand the formulas, only how to implement them. Rather than trying to figure out one big formula, do each piece as its own statement, and store the result in a variable. You may find it easiest to work backwards. So you might start with a statement that looks similar to this:

    double ax = Fx / m;

In order to compute ax, you need to first compute Fx. So based on the formula in the figure, you would add a new statement before this one:

    double Fx = F * dx / d;
    double ax = Fx / m;

Next add statements to compute dx and r. You'll end up with a series of statements that are easy to write and understand, and that ultimately compute the new positions.

My computer doesn't display the animation smoothly. Is there anything I can do? Use StdDraw.show(30) to turn on the animation mode of standard draw. Call it once at the end of each time step, not after each drawing command.

Can I combine Steps 1, 2, and 3 into one massive loop? No! You must do Step 1 (compute all of the forces) before Steps 2 and 3 (moving and drawing them); otherwise, you will be computing the forces at time t using the positions of some of bodies at time t and others at time t + Δt. Of course, the three steps comprise the body of the main simulation loop.

I draw the bodies, but nothing appears on the screen. Why? Use StdDraw.setXscale() and StdDraw.setYscale() to change the coordinate system to use the physics coordinates instead of the unit box.

My bodies repel each other. Why don't they attract each other? Make sure that you get the sign right when you apply Newton's law of gravitation: (x[j] - x[i]) vs. (x[i] - x[j]). Note that Δx and Δy can be positive or negative so do not use Math.abs(). Do not consider changing the universal gravitational constant G to patch your code!

What is Δx? It's the change in x-coordinate between two bodies (not between a body at time t and at time t + Δt).

How many steps should my program simulate if T is not a multiple of ΔT? Simulate the universe as long as t < T. For example, if T is 50,000 and ΔT is 25,000, you should simulate the system for two steps (t = 0 and 25,000). If T is 60,000 and ΔT is 25,000, you should simulate the system for three steps (t = 0, 25,000 and 50,000).

Does my program need to plot anything if T equals 0? No, you do not need to plot anything.

When I compile NBody.java, it says "cannot resolve symbol StdDraw." Any thoughts? Be sure you have either StdDraw.java or StdDraw.class in the current directory.

Everything works until I add StdAudio.play("2001.mid") then everything hangs. What do I do? On some machines there may be a race problem between sending things to the drawing window and sending things to the sound card. Try moving StdAudio.play() to a place in the program after your initial calls to StdDraw.setXscale() and StdDraw.setYscale().

I can play MP3s using my favorite media player, but no sound plays in Java. What could be wrong? If you are running Windows XP, be sure that the audio stream that Java uses is not muted via Start -> Programs -> Accessories -> Multimedia -> Volume Control -> Wave Out.

Testing and Debugging

Inserting print statements is a good way to trace what your program is doing. Our input files were created with the following StdOut.printf() statements.

StdOut.printf("%d\n", N);
StdOut.printf("%.2e\n", R);
for (int i = 0; i < N; i++) {
    StdOut.printf("%11.4e %11.4e %11.4e %11.4e %11.4e %12s\n",
                   px[i], py[i], vx[i], vy[i], mass[i], image[i]);
Here are our results for a few sample inputs.
% java NBody 0.0 25000.0 < planets.txt           // zero steps
 1.4960e+11  0.0000e+00  0.0000e+00  2.9800e+04  5.9740e+24    earth.gif
 2.2790e+11  0.0000e+00  0.0000e+00  2.4100e+04  6.4190e+23     mars.gif
 5.7900e+10  0.0000e+00  0.0000e+00  4.7900e+04  3.3020e+23  mercury.gif
 0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00  1.9890e+30      sun.gif
 1.0820e+11  0.0000e+00  0.0000e+00  3.5000e+04  4.8690e+24    venus.gif

% java NBody 25000.0 25000.0 < planets.txt       // one step
 1.4960e+11  7.4500e+08 -1.4820e+02  2.9800e+04  5.9740e+24    earth.gif
 2.2790e+11  6.0250e+08 -6.3860e+01  2.4100e+04  6.4190e+23     mars.gif
 5.7875e+10  1.1975e+09 -9.8933e+02  4.7900e+04  3.3020e+23  mercury.gif
 3.3087e+01  0.0000e+00  1.3235e-03  0.0000e+00  1.9890e+30      sun.gif
 1.0819e+11  8.7500e+08 -2.8329e+02  3.5000e+04  4.8690e+24    venus.gif

% java NBody 50000.0 25000.0 < planets.txt       // two steps
 1.4959e+11  1.4900e+09 -2.9640e+02  2.9799e+04  5.9740e+24    earth.gif
 2.2790e+11  1.2050e+09 -1.2772e+02  2.4100e+04  6.4190e+23     mars.gif
 5.7826e+10  2.3945e+09 -1.9789e+03  4.7880e+04  3.3020e+23  mercury.gif
 9.9262e+01  2.8198e-01  2.6470e-03  1.1279e-05  1.9890e+30      sun.gif
 1.0818e+11  1.7499e+09 -5.6660e+02  3.4998e+04  4.8690e+24    venus.gif

% java NBody 60000.0 25000.0 < planets.txt       // three steps
 1.4958e+11  2.2349e+09 -4.4460e+02  2.9798e+04  5.9740e+24    earth.gif
 2.2789e+11  1.8075e+09 -1.9158e+02  2.4099e+04  6.4190e+23     mars.gif
 5.7752e+10  3.5905e+09 -2.9682e+03  4.7839e+04  3.3020e+23  mercury.gif
 1.9852e+02  1.1280e+00  3.9705e-03  3.3841e-05  1.9890e+30      sun.gif
 1.0816e+11  2.6248e+09 -8.4989e+02  3.4993e+04  4.8690e+24    venus.gif

% java NBody 31557600.0 25000.0 < planets.txt    // one year
 1.4959e+11 -1.6531e+09  3.2949e+02  2.9798e+04  5.9740e+24    earth.gif
-2.2153e+11 -4.9263e+10  5.1805e+03 -2.3640e+04  6.4190e+23     mars.gif
 3.4771e+10  4.5752e+10 -3.8269e+04  2.9415e+04  3.3020e+23  mercury.gif
 5.9426e+05  6.2357e+06 -5.8569e-02  1.6285e-01  1.9890e+30      sun.gif
-7.3731e+10 -7.9391e+10  2.5433e+04 -2.3973e+04  4.8690e+24    venus.gif

Possible Progress Steps

These are purely suggestions for how you might make progress. You do not have to follow these steps. If you get stumped or frustrated on some portion of the assignment, you should not hesitate to consult a preceptor.