// cube2.java
// 3D object in perspective

import java.applet.*;   		// applet classes
import java.awt.*;			// user interface classes
import java.awt.event.*;		// event handling classes
import java.io.*;			// for screen I/O

public class cube2 extends Applet {

	int [] x;
	int [] y;
	int [] z;
	int [] px;
	int [] py;
	int size = 100;
	int upperleftx = size;
	int upperlefty = size;
	int upperleftz = size;
	int delay = 200;
	int solidFlag = 0;
	int perspectFlag = 0;
	Color myColor, myColor2;

	public void paint (Graphics grafObj) {
		int i, j;

		grafObj.setColor (myColor);

		if (perspectFlag == 0) {
			// front
			if (solidFlag == 0) { 
				grafObj.drawPolygon (x, y, 4);
			} else {
				grafObj.fillPolygon (x, y, 4);
			}
			// back
			for (i = 4; i < 7; i++) 
				grafObj.drawLine (x[i], y[i], x[i+1], y[i+1]);
			grafObj.drawLine (x[7], y[7], x[4], y[4]);
			// sides
			for (i = 0, j = 4; j < 8; i++, j++)  
				grafObj.drawLine (x[i], y[i], x[j], y[j]);
		} else {		// perspectFlag == 1
			// front
			if (solidFlag == 0) { 
				grafObj.drawPolygon (px, py, 4);
			} else {
				grafObj.fillPolygon (px, py, 4);
			}
			// back
			for (i = 4; i < 7; i++) 
				grafObj.drawLine (px[i], py[i], px[i+1], py[i+1]);
			grafObj.drawLine (px[7], py[7], px[4], py[4]);
			// sides
			for (i = 0, j = 4; j < 8; i++, j++)  
				grafObj.drawLine (px[i], py[i], px[j], py[j]);
		}
	}  // paint


	public void init () {
		// using left-handed system
		int i;
	
		x = new int [8];
		y = new int [8];
		z = new int [8];
		px = new int [8];
		py = new int [8];

		// front plane
		x[0] = upperleftx;
		y[0] = upperlefty;
		z[0] = upperleftz;

		x[1] = upperleftx + size;
		y[1] = upperlefty;
		z[1] = upperleftz;

		x[2] = upperleftx + size;
		y[2] = upperlefty + size;
		z[2] = upperleftz;

		x[3] = upperleftx;
		y[3] = upperlefty + size;
		z[3] = upperleftz;

		// back plane
		x[4] = upperleftx;
		y[4] = upperlefty;
		z[4] = upperleftz + size;

		x[5] = upperleftx + size;
		y[5] = upperlefty;
		z[5] = upperleftz + size;

		x[6] = upperleftx + size;
		y[6] = upperlefty + size;
		z[6] = upperleftz + size;

		x[7] = upperleftx;
		y[7] = upperlefty + size;
		z[7] = upperleftz + size;

		// blueish
		myColor = new Color (100, 0, 255);

		// set up some buttons
		Button solid = new Button ("Solid");
		solid.addActionListener (new makeSolid ());
		Button perspect = new Button ("Perspective");
		perspect.addActionListener (new doPerspect());

		add (solid);
		add (perspect);

	}  // init

	private class makeSolid implements ActionListener {
		public void actionPerformed (ActionEvent event) {
			if (solidFlag == 1) {
				solidFlag = 0;
			} else {
				solidFlag = 1;
			}
			repaint ();
		}
	}

	private class doPerspect implements ActionListener {
		public void actionPerformed (ActionEvent event) {
			if (perspectFlag == 1) {
				perspectFlag = 0;
			} else {
				perspectFlag = 1;
				perspective ();
			}
			repaint ();
		}
	}

	void perspective () {
	// multiply points by perspective projection matrix
		int i;
		float w;
		float d = 500;

		for (i = 0; i < 8; i++) {
			w = z [i] / d + 1;
			px [i] = (int) (x [i] / w);
			py [i] = (int) (y [i] / w);
		}
	}  // perspective

}  // program
