public class Gear extends Shape {
	public double Smallify=1.5, CogWidth = .1, CogLength = .3,
		Taper = .95;
	final int COGS;
	// i should build this up from cylinder and cubes,
	// but that requires a little architecting 
	// (and transform tree) and i'd
	// also have to remove interior edges in order to get
	// the effect i want.
	// also i don't actually do the face
	public Gear(int cogs) {
		super(cogs*16,cogs*4,4);
		COGS = cogs;
	}
	public void build() {
		final double
			INR = 1. - CogLength,
			INC = Math.PI*INR*2.;
		for(int i = 0; i<COGS; ++i) {
			double a = 2*i*Math.PI/COGS,
				a2 = a + CogWidth/INR/Smallify,
				c = (a+a2)/2.,
				b = c-Taper*CogWidth/2./Smallify, 
				b2 = c+Taper*CogWidth/2/Smallify,
				an = a+2.*Math.PI/COGS/Smallify;
			Vector3D p1 = new Vector3D(INR*Math.cos(a), INR*Math.sin(a),.5),
				p2 = new Vector3D(Math.cos(b), Math.sin(b),0.5),
				p3 = new Vector3D(Math.cos(b2), Math.sin(b2),0.5),
				p4 = new Vector3D(INR*Math.cos(a2), INR*Math.sin(a2), 0.5),
				p5 = new Vector3D(INR*Math.cos(an), INR*Math.sin(an), 0.5),
				p1b = new Vector3D(p1),
				p2b = new Vector3D(p2),
				p3b = new Vector3D(p3),
				p4b = new Vector3D(p4),
				p5b = new Vector3D(p5);
			double cf = c-Math.PI/2,
				ccf = c+Math.PI/2;
			Vector3D vc = new Vector3D(Math.cos(cf),Math.sin(cf),0.),
				ve = new Vector3D(Math.cos(c),Math.sin(c),0.),
				vcc = new Vector3D(Math.cos(ccf),Math.sin(ccf),0.),
				vb = new Vector3D(Math.cos((a2+an)/2.),Math.sin((a2+an)/2.),0.);
			p1b.set(2,p2b.set(2,p3b.set(2,p4b.set(2,p5b.set(2,-0.5)))));	
			vertices_[i*16   ] = new PointyPoint(p1,vc);
			vertices_[i*16+1 ] = new PointyPoint(p1b,vc);
			vertices_[i*16+2 ] = new PointyPoint(p2b,vc);
			vertices_[i*16+3 ] = new PointyPoint(p2,vc);
			 
			vertices_[i*16+4 ] = new PointyPoint(p2,ve);
			vertices_[i*16+5 ] = new PointyPoint(p2b,ve);
			vertices_[i*16+6 ] = new PointyPoint(p3b,ve);
			vertices_[i*16+7 ] = new PointyPoint(p3,ve);
			
			vertices_[i*16+8 ] = new PointyPoint(p3,vcc);
			vertices_[i*16+9 ] = new PointyPoint(p3b,vcc);
			vertices_[i*16+10] = new PointyPoint(p4b,vcc);
			vertices_[i*16+11] = new PointyPoint(p4,vcc);
 
			vertices_[i*16+12] = new PointyPoint(p4,vb);
			vertices_[i*16+13] = new PointyPoint(p4b,vb);
			vertices_[i*16+14] = new PointyPoint(p5b,vb);
			vertices_[i*16+15] = new PointyPoint(p5,vb);
			for(int j = 0; j<4; ++j)
				for(int k = 0; k<4; ++k)
					faces_[i*4+j][k] = i*16+j*4+k;
		}
	}
	public Gear[] next_ = new Gear[4];
	public void spin(double d) {
		double a = d/((1.-CogLength/2.)*scaleX_);
		setRotationZ(zrot_+a);
		for(int i=0; i<4; ++i)
			if(next_[i]!=null)
				next_[i].spin(-d);
	}
}
