All pastes #737749 Raw Edit

Jemand

public java v1 · immutable
·published 2007-10-15 18:02 UTC
rendered paste body
import java.awt.Point;import java.awt.Color;/** * Abstract representation of a polygon. * Includes code for clipping. * Subclasses need to provide implementation of drawing. */abstract public class CG1Polygon{	public static final int LEFT = 0;	public static final int RIGHT = 1;	public static final int BOTTOM = 2;	public static final int TOP = 3;	public static final int X = 0;	public static final int Y = 1;	public static final int Z = 2;	/// unclipped vertices (in screen coordinates)	protected CG1Point[] vertices;	/// clipped vertices (in screen coordinates)	protected int[][] clipped;	/// depths associated with the vertices	protected double[] depth;	protected int numVertex;	protected Color color;	protected Point wMin, wMax;	protected int cnt;	protected CG1Point[] first;	protected CG1Point[] s;	public CG1Polygon (CG1Point[] _vertices, Color _color)	{		vertices = _vertices;		color = _color;		numVertex = vertices.length;		clipped = new int[2*numVertex + 1][2];		depth = new double[2*numVertex + 1];		first= new CG1Point[4];		s= new CG1Point[4];	}	/**	 * Draw the clipped polygon.	 */	abstract protected void drawClipped (CG1Canvas canvas);	/**	 * Clip vertices of the polygon, then call the specific method for drawing.	 */	public void draw (CG1Canvas canvas)	{		clip (canvas);		drawClipped (canvas);	}	/**	 * Find out if a point is inside the clipping window, as seen from the specified edge.	 */	protected boolean inside (CG1Point point, int edge)	{		/**		 * TODO 2:		 * - Implement this method.		 */		CG1Point p=point;		//System.out.println("insidep:"+p+"||Edge:"+edge);		switch (edge){		case LEFT: if(p.x<wMin.x) {return false;}  break;// else { return true; } //linke ClippingGrenze wird ueberprueft		case RIGHT: if(p.x>wMax.x){ return false;} break; // else { return true; } //rechte clippingGrenze		case BOTTOM: if(p.y<wMin.y){ return false;} break;// else {return true; }//unten		case TOP: if(p.y>wMax.y) {return false;} break;// else {return true; }//oben		}		return true;	}	/**	 * Find out if the line between two vertices cross the specified edge.	 */	protected boolean cross (CG1Point p1, CG1Point p2, int edge)	{		/**		 * TODO 2:		 * - Implement this method.		 */		CG1Point p1_=p1;		CG1Point p2_=p2;		if (inside(p1_, edge)==inside(p2_, edge)){			return false; //wenn inside fuer beide Pkte das gleiche ergibt 		}		return true;	}	/**	 * Calculate intersection point of a line and a specified edge.	 */	protected CG1Point intersect (CG1Point p1, CG1Point p2, int edge)	{		/**		 * TODO 2:		 * - Implement this method.		 * - Note that our points have a z-component, which should also be set correctly for an intersection point!		 *   To do this, calculate an interpolated value at the right distance between the z values of p1 and p2.		 *   (This is an addition to the algorithm implementation in the Hearn&Baker book.)		 */		CG1Point ipt=new CG1Point(0.0, 0.0, 0.0);		double t;  //Verhaeltnis groesserem Dreieck zu kleinerem		double s;		switch (edge){		case LEFT:			t=(wMin.x-p1.x)/(p2.x-p1.x);			ipt.x=wMin.x;			ipt.y=p1.y+t*(p2.y-p1.y);			ipt.z=p1.z+t*(p2.z-p1.z);			break;		case RIGHT:			t=(wMax.x-p1.x)/(p2.x-p1.x);			ipt.x=wMax.x;			ipt.y=p1.y+t*(p2.y-p1.y);			ipt.z=p1.z+t*(p2.z-p1.z);			break;		case BOTTOM:			t=(wMin.y-p1.y)/(p2.y-p1.y);			ipt.y=wMin.y;			ipt.x=p1.x+t*(p2.x-p1.x);			ipt.z=p1.z+t*(p2.z-p1.z);			break;		case TOP:			t=(wMax.y-p1.y)/(p2.y-p1.y);			ipt.x=p1.x+t*(p2.x-p1.x);			ipt.y=wMax.y;			ipt.z=p1.z+t*(p2.z-p1.z);			break;		}		if (edge<4) {			return(ipt); 		}else{ 			return(null);		}	}	/**	 * Clip a point to the specified edge.	 */	protected void clipPoint (CG1Point point, int edge)	{		/**		 * TODO 2:		 * - Implement clipping using the Sutherland-Hodgeman algorithm.		 * - Note that our points have a z-components. To 'output' a final clipped point,		 *   put its x/y-coordinates into the clipped[] array, and its associated z-coordinate into depth[].		 *   (This is an addition to the algorithm implementation in the Hearn&Baker book.)		 */		CG1Point p=point;		//System.out.println("clipPointp:"+p);		if (first[edge]==null){			first[edge]=p; //erster Punkt, der bei der Kante ueberprueft wird, wird in das first[] gespeichert		}else{ //wenn schon ein Punkt an der Kante behandelt worden ist			//System.out.println("cross:"+(cross(p, s[edge], edge)));			if (cross(p, s[edge], edge)){ //schneide die aktuelle Kante die vorherige an der Kante behandelte?				CG1Point ipt = intersect(p, s[edge], edge); //Schnittpunkt wird ausgerechnet				//System.out.println("intersect ipt:"+ipt);				if (edge<TOP){ //wenn die zu ueberpruefende Kante nicht Top ist					clipPoint(ipt, edge+1); //Funktion wird rekursiv aufgerufen mit dem Schnittpunkt und der naechsten Kante				}else{					clipped[cnt][X]=(int)ipt.x;//ausgabe in das clipped[][]					clipped[cnt][Y]=(int)ipt.y;					depth[cnt]=ipt.z;			        cnt++;//Kantencounter wird erhoeht				}			}		}						s[edge]=p;//aktueller Punkt wird fuer diese Kante gespeichert		if (inside(p, edge)){ //wenn diser Punkt innerhalb der clippingkante ist			if (edge <TOP){ //und die Kante nicht TOP ist				clipPoint(p, edge+1); //Funktion wird rekursiv fuer die naechste Kante aufgerufen			}else{ 				clipped[cnt][X]=(int)p.x;				clipped[cnt][Y]=(int)p.y;				depth[cnt]=p.z;				cnt++; //Kantencounter wird erhoeht			}		}		//System.out.println("first["+edge+"]:"+first[edge]);		//System.out.println("s["+edge+"]:"+s[edge]);	}			/**	 * Finish the clipping procedure.	 */	protected void closeClip ()	{		/**		 * TODO 2:		 * - Implement clipping using the Sutherland-Hodgeman algorithm.		 * - Note that our points have z-components. To 'output' a final clipped point,		 *   put its x/y-coordinates into the clipped[] array, and its associated z-coordinate into depth[].		 *   (This is an addition to the algorithm implementation in the Hearn&Baker book.)		 * - There is also a bug in the implementation of the book: In closeClip(), the final segment of the polygon 		 *   should only be clipped against an edge, if we clipped against that edge at least once before. Add an		 *   if-statement to check for this. If we do not do this, the algorithm will fail for any polygon that lies		 *   completely outside an edge.		 */		for (int edge=LEFT; edge <=TOP;  edge++){		if (first[edge]!=null){ 			if (cross(s[edge], first[edge], edge)){ //schneidet die Linie aus erster und letzter fuer die Clippingkante gespeicherten Punkte die Clippingkante				CG1Point pt=intersect(s[edge], first[edge], edge); //Schnittpunkt berechnet 				if (edge <TOP){					clipPoint(pt, edge); //clipPointfunktion fuer schnittpunkt und clippingkante				}else{					clipped[cnt][X]=(int)pt.x;					clipped[cnt][Y]=(int)pt.y;					depth[cnt]=pt.z;					cnt++;				}			}		}}	}	/**	 * Clip all vertices of this polygon.	 */	protected void clip (CG1Canvas canvas)	{		wMin = new Point (1, 1);		wMax = new Point (canvas.getWidth()-2, canvas.getHeight()-2);		/**		 * TODO 2:		 * - Implement clipping using the Sutherland-Hodgeman algorithm.		 * - The numVertex member variable contains the number of vertices in this polygon.		 *   Be sure to update it accordingly after clipping is complete.		 */				int nClip=4;		for (int i=0; i<nClip; i++){//initialisierung der first und s arrays mit null			first[i]=null;			s[i]=null;		}		cnt=0;				for (int k=0; k<numVertex; k++){			//System.out.println("vertice["+k+"]:"+vertices[k]);			clipPoint(vertices[k], LEFT);			//System.out.println("vertice["+k+"] nach Clip:"+vertices[k]);		}		closeClip();		numVertex=cnt;//Aktualisierung der Punktanzahl des sichtbaren Polygons				/*for (int i=0; i<numVertex; i++)		{			clipped[i][X] = (int)vertices[i].x;			clipped[i][Y] = (int)vertices[i].y;		}*/	}	/**	 * Debug output.	 */	public void print_vertices ()	{		for (int i=0; i<numVertex; i++)		{			System.out.println ("Point " + i + ": X=" + vertices[i].x + " Y=" + vertices[i].y + " Z=" + vertices[i].z);		}		System.out.println ();	}	/**	 * Debug output.	 */	public void print_clipped ()	{		for (int i=0; i<numVertex; i++)		{			System.out.println ("Point " + i + ": X=" + clipped[i][X] + " Y=" + clipped[i][Y]);		}		System.out.println ();	}}