/** * Copyright (c) 2005-2006 by Hank Dolben * Licensed under the Open Software License version 2.1 * http://opensource.org/licenses/osl-2.1.php */ package org.dolben.poly; import java.awt.Color; import java.awt.Graphics; import org.dolben.iiid.*; import org.dolben.poly.Polyhedron; /** * A polyhedron drawn as colored faces. */ public class ColoredFaces extends Solid { protected Lighting lighting; // the lighting of the scene /** * Creates a new Solid for a given polyhedron. * * @param poly the polyhedron to be drawn */ public ColoredFaces( Polyhedron poly ) { super(poly); lighting = new Lighting(); } /** * Gets the color of a polygon based on the number of its sides. */ protected Color getColor( int index ) { int[] f = polyhedron.getFaceIndices(index); switch ( f.length ) { case 3: return Color.blue; case 4: return Color.red; case 5: return Color.green; case 6: return Color.cyan; case 8: return Color.pink; case 10: return Color.orange; default: return Color.gray; } } /** * Draws the polyhedron. * * @param projector the projector that maps 3D to Graphics coordinates * @param graphics the drawing context */ public void paint( Projector projector, Graphics graphics ) { /* * Each face polygon is drawn and then filled. * If it is only filled, thin gaps are left along the edges. * * All of the common heavy lifting for both draw and fill * is done up front. */ int p[][] = projector.project(polyhedron.getVertices()); double normal[][] = new double[polyhedron.getFaces()][]; Color color[] = new Color[normal.length]; boolean showing[] = new boolean[normal.length]; for ( int i = 0; i < normal.length; ++i ) { double point[][] = polyhedron.getFace(i); normal[i] = R3.cross( Rn.subtract(point[1],point[0]),Rn.subtract(point[2],point[1]) ); showing[i] = Rn.dot( normal[i],Rn.subtract(projector.getViewer(),point[0]) ) > 0; if ( showing[i] ) { color[i] = lighting.getShade(normal[i],getColor(i)); } } for ( int i = 0; i < polyhedron.getFaces(); ++i ) { if ( showing[i] ) { graphics.setColor(color[i]); int[][] xy = getFacePoints(p,i); graphics.drawPolygon(xy[0],xy[1],xy[0].length); } } for ( int i = 0; i < polyhedron.getFaces(); ++i ) { if ( showing[i] ) { graphics.setColor(color[i]); int[][] xy = getFacePoints(p,i); graphics.fillPolygon(xy[0],xy[1],xy[0].length); } } } /** * Returns the x and y coordinates of a projected face */ private int[][] getFacePoints( int[][] vertex, int index ) { int[] f = polyhedron.getFaceIndices(index); int[][] point = new int[2][f.length]; for ( int i = 0; i < f.length; ++i ) { int j = f[i]; point[0][i] = vertex[0][j]; point[1][i] = vertex[1][j]; } return point; } }