import java.awt.*; public class test2 extends MISApplet { // MATERIAL PROPERTIES double ambientColor[] = { 0.2, 0.2, 0.2 }; double diffuseColor[] = { 0.8, 0.8, 0.8 }; double specularColor[] = {1,1,1}; double specularPower = 10.0; // LIGHTING PROPERTIES double lightDirections[][] = { {1,1,1} , {-1,0,0} , {1,-1,0} }; double lightColors[][] = { {1.0,1.0,1.0}, {0.4,0.0,0.0}, {0.4,0.4,0.0} }; public void initialize() { for (int l = 0 ; l < lightDirections.length ; l++) normalize(lightDirections[l]); } public void initFrame(double time) { radius = 0.2 + 0.1 * Math.cos(0.5 * time); lightDirections[0][0] = Math.cos(time) * .5; lightDirections[0][2] = Math.sin(time) * .5; normalize(lightDirections[0]); } public void setPixel(int x, int y, int rgb[]) { // START OUT WITH A BLACK PIXEL rgb[0] = rgb[1] = rgb[2] = 0; // IF ON A SPHERE double X = (x - W/2) / (radius * W); double Y = -(y - H/2) / (radius * W); double RR = X * X + Y * Y; if (RR < 1.0) { double Z = Math.sqrt(1.0 - RR); point[0] = normal[0] = X; point[1] = normal[1] = Y; point[2] = normal[2] = Z; // ADD AMBIENT for (int i = 0 ; i < 3 ; i++) color[i] = ambientColor[i]; // LOOP THROUGH ALL LIGHT SOURCES for (int l = 0 ; l < lightDirections.length ; l++) { // COMPUTE DIFFUSE double n_dot_l = dot(lightDirections[l], normal); if (n_dot_l > 0) for (int i = 0 ; i < 3 ; i++) diffuse[i] = diffuseColor[i] * n_dot_l; else for (int i = 0 ; i < 3 ; i++) diffuse[i] = 0; // COMPUTE REFLECTION DIRECTION for (int i = 0 ; i < 3 ; i++) reflection[i] = 2 * n_dot_l * normal[i] - lightDirections[l][i]; double r_dot_e = dot(reflection, eyeDirection); // COMPUTE SPECULAR if (r_dot_e > 0) { double specularFactor = Math.pow(r_dot_e, specularPower); for (int i = 0 ; i < 3 ; i++) specular[i] = specularColor[i] * specularFactor; } else for (int i = 0 ; i < 3 ; i++) specular[i] = 0; // ADD DIFFUSE AND SPECULAR for (int i = 0 ; i < 3 ; i++) color[i] += lightColors[l][i] * (diffuse[i] + specular[i]); } // SEND COLOR TO THE FRAME BUFFER for (int i = 0 ; i < 3 ; i++) { double shade = Math.max(0, Math.min(1.0, color[i])); rgb[i] = (int)(255 * shade); } } } // USEFUL MATH public void normalize(double vec[]) { double len = norm(vec); for (int i = 0 ; i < 3 ; i++) vec[i] /= len; } public double norm(double vec[]) { return Math.sqrt(dot(vec, vec)); } public double dot(double a[], double b[]) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } // WORKING VARIABLES double color[] = new double[3]; double diffuse[] = new double[3]; double specular[] = new double[3]; double point[] = {0,0,0}; double normal[] = {0,0,0}; double eyeDirection[] = {0,0,1}; double reflection[] = {0,0,0}; double radius = 0.2; }