Sphere Raytracing


This browser does not have a Java Plug-in.
Get the latest Java Plug-in here.
Run as a Java Web Start application

If you have never used this program before, read below first.

Security Warning

You may be prompted about a "Security Warning" (because I am using a self-signed certificate). To resolve this restriction you will need to go to the Control Panel in Windows (or System Preferences on Mac), open the settings for Java, go to the Security tab, and add this website (http://www.mindtrace.net) to the Exception Site List. (On a Mac, you may still have to modify other settings to get this application to run.)

If you don't want to read the full instructions, do this.

Click on the "Start Spheres" button. A window should pop up. Click on the button that says "Generate random sphere definition". Click on the button that says "Draw image". Another window should pop up, and after a few seconds an image should display. To do another image, click again on "Generate random sphere definition", and then click "Draw image". This will bring up another window with a new image, in addition to the first image.

The full instructions

This program draws a 3D image of a group of spheres. You can specify the number, location, size, and color of the spheres and specify the position of the light ray which shines on the spheres. You can also have the program generate a random arrangement for you. A sample image is shown below.

Sample Image

This image was generated based upon the following sphere definition.

# this is a comment line, you can also put comments at the end of any line
sample
480 200 6
140   40  30 200   mediumorchid
25    50  40   0   sandybrown
120  200 100 400   khaki
60   360 145   0   110 100 200
100  340  80 600   240  50   0
6    445 150   0   darkorange
100 100 -100

Ignoring comment lines, the first line of the definition is just a name for the definition. The second line lists the dimensions of the image (400 x 160) and the number of spheres (6). Then for each sphere, a line follows listing the radius, location (x, y, z coordinates), and color. Each color may be specified either by RGB values (red, green, blue) 0-255 (ex. 200 180 120), a standard HTML color name (ex. lightgreen), or a hex string (ex. #0055aa). An x coordinate of 0 indicates the left edge of the image. A y coordinate of 0 indicates the top edge of the image. A z coordinate of 0 indicates that a sphere is very close to you. A z coordinate of greater than 0 means that a sphere is farther way. So, if one sphere has z coordinate of 0 and another has a z coordinate of 100, then the first sphere will be in front of the second, and possibly block the second if it is bigger. The last line of the definition is the location (x, y, z) of the lightsource. A location of 100, 100, -100 means that the light source will shine at a 45 degree angle from the lower left hand part of each sphere.

To use the program, click on the "Start Spheres" button. A window will pop up. To start, copy the sample image definition from above into the text area in this window. The hit the "Draw image" button. Another window will pop up, and after a few seconds you should see the same image as displayed above. Now you can experiment by making up your own image definitions.

To have the program randomly generate an image definition for you, click on the "Generate random sphere definition" button. This will fill the text area with a new image definition (and erase anything was was in the text area before). Then you can click "Draw image" to see what this definition looks like.

You can control the random definition generation to some degree by specifying basic parameters such as the size of the image, the number of spheres, and which edges of the image the spheres are allowed to cross.

About saving images: From the display window for an image you can hit the "Save As" button to save the generated image. Images are saved in PNG format. You may get a SecurityException and not be able to save your image if you did not accept my security certificate when the program first loaded.

Basic Sphere Raytracing Algorithm (for those interested)

Suppose you have the following defined:

Here is some Java-like code to calculate the light intensity value (8-bit grayscale) at a particular 2D point of the image you want to generate to represent the 3D data: (This assumes the "color" of each sphere is pure white, or 255 in 8-bit grayscale.) (Extending this to color simply requires one to assign each sphere an RGB color instead of pure white, and do calcuations for R, G, B color intensity values.)

byte calculatePoint(x, y, Sphere [] sa) {
  // smallestZ will end up being the z of the visible sphere
  double smallestZ = Double.MAX_VALUE;
  int visibleSphere = -1;

  for (int i = 0; i < sa.length; i++) {
    // Check that sphere exists at this pixel
    double temp = square(sa[i].getRadius())
           - square(x - sa[i].getCenter().getX())
           - square(y - sa[i].getCenter().getY());
    if (temp >= 0) {  // sphere does exist
      temp = sa[i].getCenter().getZ() - Math.sqrt(temp);  // so calculate z coord.

      if (temp < smallestZ)  {        // If this sphere in front of others
        smallestZ = temp;             // then update info on front sphere
        visibleSphere = i;
      }
    }
  } // end for

  if (smallestZ == Double.MAX_VALUE) { // or could say if (visibleSphere == -1)
    return 0;
  }
  else  {
    double dotProduct = calcDotProduct(x, y, smallestZ, sa[visibleSphere].getCenter(), normalizedLS);
    if (dotProduct <= 0) {
      return 0;
    }
    else  {
      return (byte) Math.round(255 * dotProduct);
    }
  }
}

double square(double d) {
  return d * d;
}

double calcDotProduct(int x, int y, double z, Point3D cen, Point3D ls) {
  // cen stands for sphereCenter, ls stands for normalized light source
  double num = (x - cen.getX()) * ls.getX()
    + (y - cen.getY()) * ls.getY()
    + (z - cen.getZ()) * ls.getZ();
  double den = Math.sqrt(square(x - cen.getX())
                  + square(y - cen.getY())
                  + square(z - cen.getZ()));
  return  num / den;
}

Valid XHTML 1.0!