Homework 2, due Friday morning, Feb 12

Well, there was no way you were going to be able to implement everything we covered in class as of yesterday (except for a few hardy souls - you know who you are...), so I'm only going to give you some of it to implement.

Basically, I'm going to ask you to implement the flying saucer, and to do that, I'm going to ask you to implement a simple version of intersect (one that only handles convex objects). For this assignment, please send all the code to the grader. Important: all your code should be able to compile (the grader won't like it if you send obviously untested code...)!

First, you'll need to define a generic Shape class, from which all your various types of shapes will be derived:

   public abstract class Shape
   {
      abstract int ray(Ray ray, double[] t); // implemented by each type of Shape

      int intersect(int n1, double[] t1, int n2, double[] t2, double[] t) {
	 /* YOUR CODE GOES HERE */
      }
   }
In the above class definition, the ray method is declared to be abstract because each type of Shape (Sphere, Box, etc.) will need to implement a version of it. Because it contains an abstract method, Shape itself must be declared abstract.

You'll also need to define a Ray class. Here is a sort of brain-dead working version of this just to get going. Later we'll get fancier:

   public class Ray
   {
      public double[] v = new double[3];
      public double[] w = new double[3];
   }
Part one of this week's assignment: Implement a simple version of the intersect method, which handles only convex shapes (ie: n1 and n2 are each guaranteed to be either zero or two).

Notes to help you to implement this: If either n1 or n2 is zero, then just return zero. Otherwise, set t[0] to be the maximum of t1[0] and t2[0], and set t[1] to be the minimum of t1[1] and t2[1]. If it then turns out that t[0] < t[1], then return two. Otherwise, return zero.

Part two of this week's assignment: Reimplement your raySphere routine as a ray method in a Sphere class:

   class Sphere extends Shape
   {
      double[] center = new double[3];
      double radius;

      Sphere(double[] center, double radius) {
	 for (int i = 0 ; i < 3 ; i++)
	    this.center[i] = center[i];
         this.radius = radius;
      }

      int ray(Ray ray, double[] t) {
	 /* YOUR CODE GOES HERE */
      }
   }
Your implementation should always return either zero or two. When you solve the quadratic equation, clip the resulting values of t so that they are non-negative. Ie: if your t[0] is negative (which means the eyepoint is inside the sphere), then change it to 0.0; if both t[0] and t[1] are negative (which means the entire sphere is behind the eyepoint), then there is no intersection. In this case your method should simply return zero.

Part three of this week's assignment: Fill in the implementation of the ray method below. Your implementation should simply call the ray methods of the two spheres, and then intersect them.

   class FlyingSaucer extends Shape
   {
      Sphere s1, s2;

      FlyingSaucer(Sphere s1, Sphere s2) {
	 this.s1 = s1;
	 this.s2 = s2;
      }

      int ray(Ray ray, double[] t) {
	 /* YOUR CODE GOES HERE */
      }
   }