/** * @file Face.java * @author R Daniel Bergeron *

* Defines a planar face in 3 dimensions. * The face is specified by an array of Point4 vertices. We assume that * the vertices are planar and that the first 3 are not collinear, so * that we can compute the normal to the plane from them. It is also * assumed that the vertices are ordered so that the normal computed can * be treated as an outward normal -- though this assumption is not * actually used in the class code right now. *

* modified by Robert S Laramee * modification date Monday 09 Nov 98 to * Thursday 12 Nov 98 * description Added a new face constructor for an arbitrary Vector * of vertices. This turned out to be very valuable. *

* modification date Saturday 21 Nov 98 * description Added a new face constructor for an arbitrary array * of vertices. This turned out to be very valuable. * Also, a number for the number vertices was added *

* modification date Sunday 22 Nov 98 * description Added a darken ratio number and darken method that * is applied to the color shading of the faces *

* modification date Friday 27 Nov 98 * description modified toString() method * Also added a size() method that return the number * of vertices */ import java.awt.*; // for Color class import java.math.*; //import matrix.*; // for Point4, Matrix4 classes import java.util.*; // for Vector class class Face extends Shape { protected Point4 _verts[]; // WC vertices of face protected int _xvals[]; // canvas coordinates protected int _yvals[]; protected Point4 _norm; // outward normal protected int _numVerts; // the number of vertices protected double _darkenRatio = 1.0; // the default is not to darken //-------- Face ( Color rgb, Point4 p[] ) public Face ( Color rgb, Point4 p[] ) { super( rgb ); _verts = copyPoints( p ); _norm = computeNormal(); _xvals = new int[ p.length ]; _yvals = new int[ p.length ]; _numVerts = p.length; } //-------- special constructor for a triangle //-------- Face ( Color rgb, Point4 p0, Point4 p1, Point4 p2 ) public Face ( Color rgb, Point4 p0, Point4 p1, Point4 p2 ) { super( rgb ); Point4 temp[] = { new Point4( p0 ), new Point4( p1 ), new Point4( p2 ) }; _verts = temp; _xvals = new int[ 3 ]; _yvals = new int[ 3 ]; _norm = computeNormal(); _numVerts = 3; } //-------- special constructor for a quad //------ Face ( Color rgb, Point4 p0, Point4 p1, Point4 p2. Point4 p3 ) public Face ( Color rgb, Point4 p0, Point4 p1, Point4 p2, Point4 p3 ) { super( rgb ); Point4 temp[] = { new Point4( p0 ), new Point4( p1 ), new Point4( p2 ), new Point4( p3 ) }; _verts = temp; _xvals = new int[ 4 ]; _yvals = new int[ 4 ]; _norm = computeNormal(); _numVerts = 4; } /** * A special constructor for a polygon with an arbitrary Vector of * of vertices. This was intended for 3 or more vertices. * @param dr -the darken ratio * @param points -a vector array of points */ public Face (Color rgb, double dr, Vector points) { super (rgb); // to make the shape constructor happy int length = points.size(); _darkenRatio = dr; _numVerts = length; Point4 temp[] = new Point4[_numVerts]; for (int i = 0; i < _numVerts; i++) { temp[i] = new Point4((Point4)points.elementAt(i)); } _verts = temp; _xvals = new int[ _numVerts ]; _yvals = new int[ _numVerts ]; _norm = computeNormal(); } /** * A special constructor for a polygon with an arbitrary array of * of vertices. This was intended for 3 or more vertices. * @param points -a vector array of points * @param rgb -the color of the polygon */ public Face (Point4[] points, Color rgb, double dr) { super( rgb ); _darkenRatio = dr; _numVerts = points.length; Point4 temp[] = new Point4[_numVerts]; for (int i = 0; i < _numVerts; i++) { temp[i] = new Point4(points[i]); } _verts = temp; _xvals = new int[_numVerts]; _yvals = new int[_numVerts]; _norm = computeNormal(); } //-------- Face ( Face ) ----------------------------------- public Face ( Face l ) { super( l ); } //---------------------- copy () ----------------- public Shape copy ( ) { return new Face( this ); } /** * return the number of vertices * return the number of vertices this face has * return color of this face */ public int size() { return _numVerts; } public int getNumVerts() { return _numVerts; } public Color getColor() { return _color; } /** * return the vertex at index i * @param i -index * @return -the Point4 at index i */ public Point4 getVert(int i) { return _verts[i]; } /** * get the darken ratio (called from OutSerialize object) * set the darken ratio (called from InSerialize object) */ public double getDarkenRatio() { return _darkenRatio; } public void setDarkenRatio(double dr) { _darkenRatio = dr; } /** * @param g -the graphics object * @param m -a transformation matrix (not used) */ public void draw (Graphics g, Matrix4 m) { g.setColor ( darken(_color, _darkenRatio)); View.toCanvas ( _verts, _xvals, _yvals ); if ( DrawCanvas.getFillMode() == DrawCanvas.HOLLOW ) g.drawPolygon ( _xvals, _yvals, _xvals.length ); else g.fillPolygon ( _xvals, _yvals, _xvals.length ); } //---------------------- copyPoints ( Point4[] ) ----------------- private Point4[] copyPoints ( Point4[] p ) { Point4 temp[] = new Point4[ p.length ]; for ( int i = 0; i < p.length; i++ ) temp[i] = p[i]; return temp; } /** * toString * This is the old toString() method. i wanted to save it for debugging. */ public String oldToString() { String temp = "Vertices: "; for (int i=0; i < _verts.length; i++ ) { temp += _verts[i].toString() + "\n"; } temp += "normal: "; temp += _norm.toString(); return temp; } /** * This is the new toString() method modified to comply with the * assigment 5 output specifications. */ public String toString() { String temp = new String(""); for (int i=0; i < _verts.length; i++ ) { temp += pointToString(_verts[i]) + "\n\t"; } return temp; } /** * This method is used instead of the normal toString() method for * points to comply with the specifcations of assignment 5 */ private String pointToString(Point4 p) { return new String(p.x + " " + p.y + " " + p.z); } /** * computeNormal * this assumes that the 1st 3 points of the face are not * collinear. */ public Point4 computeNormal() { Point4 v1 = new Point4 ( _verts[1].x - _verts[0].x, _verts[1].y - _verts[0].y, _verts[1].z - _verts[0].z); Point4 v2 = new Point4 ( _verts[2].x - _verts[0].x, _verts[2].y - _verts[0].y, _verts[2].z - _verts[0].z); return v1.cross( v2 ); } /** * darken (Color, double darkenRatio ) * This uses the "darkenRatio" parameter as a % amount to darken the * Color. So if you want the Color to be 90% of its current * brightness, pass in .9 as the darkenRatio parameter. */ public Color darken ( Color rgb, double darkenRatio ) { if ( darkenRatio < 0 ) darkenRatio = -darkenRatio; if ( darkenRatio > 1 ) darkenRatio = 1; return new Color ( (int)(rgb.getRed()*darkenRatio), (int)(rgb.getGreen()*darkenRatio), (int)(rgb.getBlue()*darkenRatio) ); } }