/** Represents information about where a ray reaches a surface. */
public abstract class Intersection {
	/** Represents the null intersection - for when a ray
	 * doesn't meet any surface. */
	public static final Intersection NONE = new NullIntersection();

	private static class NullIntersection extends Intersection {
		public double getDistance() { return Double.POSITIVE_INFINITY; }
		public Point getHitPoint() { return Point.ORIGIN; }
		public Vector getNormal() { return Vector.ZERO; }
		public Material getMaterial() { return Material.BLACK_PLASTIC; }
	}

	public Intersection() { }

	/** Returns the distance along the ray to the intersection;
	 * ie, how many times the direction vector should be added
	 * to the point to reach the surface. This number should
	 * always be at least 1.0. */
	public abstract double getDistance();

	/** Returns the point on the surface where the ray hit. */
	public abstract Point getHitPoint();

	/** Returns a vector normal to the surface at the point
	 * where the ray hit, in the direction of the surface's
	 * exterior. */
	public abstract Vector getNormal();

	/** Returns the material on the surface at the point the
	 * ray hit. */
	public abstract Material getMaterial();
}
