import java.io.*; import java.lang.*; /** * Sphere represents a spherical object * * @author Anthony Steed * @version 1.0 */ public class Sphere extends Object { /** * Holds the point that defines the sphere centre */ public Point Centre; /** * Holds the radius of the sphere */ public double Radius; /** * Create a default sphere */ public Sphere() { SurfaceMaterial = new Material(); Centre = new Point(); Radius = 1.0; } /** * Create a sphere with the given material, centre and radius * * Note values are referenced not copied in the new object * @param n the material for the plane * @param p the centre of the sphere * @param r the radius of the sphere */ public Sphere(Material n, Point p, double r) { SurfaceMaterial = n; Centre = p; Radius = r; } /** * Find the normal of an object at the given point on its surface. * * Note that a new Vector is created on each call. * @param pt the surface point to find the normal at * @return a reference to the fixed normal of the plane */ public Vector normal(Point p) { return Vector.subtract(p,Centre).normalised(); } /** * Find the intersection of the plane and a given ray. * * The return value is positive is the intersection is found and * this value gives the distance along the ray. Negative values * imply that the intersection was either not successful or the * intersection point was before the origin. This value can be used * with the pointAt method of the Ray class (@see Ray#pointAt) * * @param ray the ray to intersect with * @return a double value that gives the distance * along the ray. */ public double intersect(Ray ray) { Vector tmp; double A,B,C,d,t1,t2,t; tmp = Vector.subtract(ray.Origin, Centre); A = ray.Direction.squarednorm(); B = Vector.dot(tmp, ray.Direction); C = tmp.squarednorm() - (Radius*Radius); if((d=((B*B)-(A*C))) < 0.0) return -1.0; // -1.0 is "false" value d = Math.sqrt(d); t = (-B-d)/A; return t; } /** * Read the sphere from the given source * @param is the source to read from * @exception java.io.IOException * if the light can not be read * @exception java.io.NumberFormatException * if there a number format error is encountered */ public void read(SceneReader is) throws IOException, NumberFormatException { Centre.read(is); Radius = is.readDouble(); SurfaceMaterial.read(is); } /** * Write the sphere to the given destination * @param os the destination to write to * @exception java.io.IOException * if the write fails. */ public void write(SceneWriter os) throws IOException { Centre.write(os); os.writeDouble(Radius); os.writeChar(' '); SurfaceMaterial.write(os); } /** * Print a human readable version of the sphere definition to the * given destination * @param os the destination to write to * @exception java.io.IOException * if the write fails. */ public void print(SceneWriter os) throws IOException { os.writeString("Sphere with centre: "); Centre.print(os); os.writeString(" and radius: "); os.writeDouble(Radius); os.writeString("\n"); SurfaceMaterial.print(os); os.writeString("\n"); } }