//<pre>
package wonderlab.graphics.shape;
import wonderlab.graphics.geometry.*;

// creates a "cylinder"
// circular surfaces are approximated by n-sided polygons
// shape's vertices are numbered as follows
// front-cap: 		0...n		(n total)
// inside-cap: 		n+1...2n	(n-1 total)
// rear-inside-cap: 2n+1...3n+1	(n-1 total)
// rear-cap:		3n+2...4n+1	(n total)
// cylinder is drawn front to back, lying on its side and facing toward +Z
// NOTE: All faces are triangles

public class Cylinder extends Shape3D {

	public Cylinder(int n) {
		super();
		vertices = new Vertex[4*n+2];
		transformedVertices = new Vertex[vertices.length];
		faces = new int[3*n*2][3];
		int curFace = 0;
		
		////////////////////////////// VERTICES /////////////////////////////////////////
		// front cap
		for (int i = 0; i < n; i++) {		
			vertices[i] = new Vertex(Math.cos(2*Math.PI*i/n),Math.sin(2*Math.PI*i/n),0.5,0,0,1.0);
		}		
		// inside cap
		vertices[n] = new Vertex(0,0,0.5,0,0,1);								// create vertex at front-center
		for (int i = n+1; i < n+n+1; i++) {	
			vertices[i] = new Vertex(Math.cos(2*Math.PI*i/n),Math.sin(2*Math.PI*i/n),0.5,Math.cos(2*Math.PI*i/n),Math.sin(2*Math.PI*i/n),1.0);
		}
		// rear-inside cap
		for (int i = n+n+1; i < n+n+n+1; i++) {	
			vertices[i] = new Vertex(Math.cos(2*Math.PI*i/n),Math.sin(2*Math.PI*i/n),-0.5,Math.cos(2*Math.PI*i/n),Math.sin(2*Math.PI*i/n),-1.0);
		}
		// rear cap
		for (int i = 3*n+1; i < 4*n + 1; i++) {
			vertices[i] = new Vertex(Math.cos(2*Math.PI*i/n),Math.sin(2*Math.PI*i/n),-0.5,0,0,-1.0);
		}
		vertices[4*n+1] = new Vertex(0,0,-0.5,0,0,-1.0);					// create vertex at back-center
		//////////////////////////////////// FACES ////////////////////////////////////
		// front cap
		for (int i = 0; i < n; i++) {	
			faces[curFace] = new int[3];			
			faces[curFace][0] = n;
			faces[curFace][1] = (i     % (n));
			faces[curFace][2] = ((i+1) % (n));
			curFace++;
		}
 		// body
		for (int i = n; i < n+n; i++) {
			int v = i - n;
			faces[curFace][0] = (  n + 1) + (v    );
			faces[curFace][1] = (  n + 1) + ((v + 1) % n);
			faces[curFace][2] = (2*n + 1) + ((v + 1) % n);
			curFace++;
			faces[curFace][0] = (  n + 1) + (v    );
			faces[curFace][1] = (2*n + 1) + ((v + 1) % n);
			faces[curFace][2] = (2*n + 1) + (v    );
			curFace++;
		}		
		// rear cap		
		for (int i = 2*n; i < 3*n; i++) {
			int v = i - 2*n;
			faces[curFace][0] = 4*n+1;
			faces[curFace][1] = (3*n + 1) + v;
			faces[curFace][2] = (3*n + 1) + ((v + 1) % n);
			curFace++;
		}
	}
		
}