public class Disc { final int X = 0; final int Y = 1; final int Z = 2; final int NX = 3; final int NY = 4; final int NZ = 5; int N; Material material; int[][] faces; double[][] vertices; public Disc(int n) { N = n; faces = new int[N-1][3]; for (int i = 0; i < N-1; i++) { faces[i][0] = 0; faces[i][1] = i + 1; faces[i][2] = (i + 2) % N; } faces[N-2][2] = 1; reset(); } public void reset() { vertices = new double[N][6]; vertices[0][X] = 0; vertices[0][Y] = 0; vertices[0][Z] = 0; vertices[0][NX] = 0; vertices[0][NY] = 0; vertices[0][NZ] = 0; for (int i = 1; i < N; i++) { vertices[i][X] = Math.cos( (i - 1) * 2 * Math.PI / (N - 1) ); vertices[i][Y] = Math.sin( (i - 1) * 2 * Math.PI / (N - 1) ); vertices[i][Z] = 0; vertices[i][NX] = 0; vertices[i][NY] = 0; vertices[i][NZ] = 1; } } public void setMaterial(Material m) { material = m.copy(); } public void bufferTo(double[][] zBuffer, double[][][] frameBuffer, Light[] lights, double focalLength) { for (int i = 0; i < faces.length; i++) { Triangle triangle = makeTriangle( vertices[faces[i][0]], vertices[faces[i][1]], vertices[faces[i][2]]); triangle.perspectiveTransform(focalLength); triangle.viewportTransform(zBuffer.length, zBuffer[0].length); triangle.calculateColors(lights); //System.out.println("Faces: " + faces[i][0] + " | " + faces[i][1] + " | " + faces[i][2]); //triangle.print(); triangle.bufferTo(zBuffer, frameBuffer); } } private Triangle makeTriangle(double[] v0, double[] v1, double[] v2) { Triangle triangle = new Triangle(); double[][] vertices = { {v0[X], v0[Y], v0[Z]}, {v1[X], v1[Y], v1[Z]}, {v2[X], v2[Y], v2[Z]} }; double[][] normals = { {v0[NX], v0[NY], v0[NZ]}, {v1[NX], v1[NY], v1[NZ]}, {v2[NX], v2[NY], v2[NZ]} }; if (normals[0][Z] < 0) { for (int i = 0; i < normals.length; i++) for (int j = 0; j < normals[i].length; j++) normals[i][j] = -1 * normals[i][j]; } triangle.setVertices(vertices); triangle.setNormals(normals); triangle.setAmbientColor(material.getAmbientColor()); triangle.setDiffuseColor(material.getDiffuseColor()); triangle.setSpecularColor(material.getSpecularColor()); triangle.setSpecularPower(material.specularPower); return triangle; } public void printVertices() { System.out.println("Vertices"); for (int i = 0; i < vertices.length; i++) { System.out.println(i + ": {" + vertices[i][X] + ", " + vertices[i][Y] + ", " + vertices[i][Z] + "}"); } } public double[][] getTransformedVertices(Matrix3D t) { double[][] newVertices = new double[vertices.length][3]; for (int i = 0; i < newVertices.length; i++) { double[] point = { vertices[i][X], vertices[i][Y], vertices[i][Z] }; double[] transPoint = t.transform(point); newVertices[i][X] = transPoint[0]; newVertices[i][Y] = transPoint[1]; newVertices[i][Z] = transPoint[2]; } return newVertices; } public double[][] getNormals(double[][] v) { double[][] gradients = new double[faces.length][3]; for (int i = 0; i < faces.length; i++) { double[] v1minusv0 = { v[faces[i][1]][X] - v[faces[i][0]][X], v[faces[i][1]][Y] - v[faces[i][0]][Y], v[faces[i][1]][Z] - v[faces[i][0]][Z] }; double[] v2minusv1 = { v[faces[i][2]][X] - v[faces[i][1]][X], v[faces[i][2]][Y] - v[faces[i][1]][Y], v[faces[i][2]][Z] - v[faces[i][1]][Z] }; // cross products gradients[i][X] = v1minusv0[Y] * v2minusv1[Z] - v1minusv0[Z] * v2minusv1[Y]; gradients[i][Y] = v1minusv0[Z] * v2minusv1[X] - v1minusv0[X] * v2minusv1[Z]; gradients[i][Z] = v1minusv0[X] * v2minusv1[Y] - v1minusv0[Y] * v2minusv1[X]; } double[][] normals = new double[vertices.length][3]; for (int i = 0; i < normals.length; i++) { normals[i][X] = 0; normals[i][Y] = 0; normals[i][Z] = 0; for (int j = 0; j < faces.length; j++) { for (int k = 0; k < faces[j].length; k++) { if (faces[j][k] == i) { normals[i][X] = gradients[j][X]; normals[i][Y] = gradients[j][Y]; normals[i][Z] = gradients[j][Z]; break; } } } double magnitude = Math.sqrt( normals[i][X] * normals[i][X] + normals[i][Y] * normals[i][Y] + normals[i][Z] * normals[i][Z] ); normals[i][X] /= magnitude; normals[i][Y] /= magnitude; normals[i][Z] /= magnitude; //System.out.println("normal " + i + " is {" + transformed[i][NX] + ", " + transformed[i][NY] + ", " + transformed[i][NZ] + "}"); } return normals; } public void transformedBy(Matrix3D t) { double[][] transVertices = getTransformedVertices(t); double[][] transNormals = getNormals(transVertices); for (int i = 0; i < vertices.length; i++) { vertices[i][X] = transVertices[i][X]; vertices[i][Y] = transVertices[i][Y]; vertices[i][Z] = transVertices[i][Z]; vertices[i][NX] = transNormals[i][X]; vertices[i][NY] = transNormals[i][Y]; vertices[i][NZ] = transNormals[i][Z]; } } }