import java.awt.*; /** Program: RotIcosa Purpose: rotate colored icosahedron, etc. @author: Paul Garrett, garrett@math.umn.edu @version: 8, Sun Feb 23 16:56:41 CST 1997 */ public class RotIcosa8 extends java.applet.Applet implements Runnable { Thread th; final Color backColor = new Color(254,222,208); // e5e5e0 (=Color.math) = 229,229,224 final Color edgeColor = Color.darkGray; final Color faceColor = Color.pink; final float theAngle = (float) (Math.PI/100.0); final float aAngle = (float) (Math.PI/8.0); final float bAngle = (float) (Math.PI/10.0); final float c = (float) Math.cos(theAngle); final float s = (float) Math.sin(theAngle); final float ca = (float) Math.cos(aAngle); final float sa = (float) Math.sin(aAngle); final float cb = (float) Math.cos(bAngle); final float sb = (float) Math.cos(bAngle); final float[][] A = {{1,0,0}, {0,ca,sa}, {0,-sa,ca}}; final float[][] Ai = {{1,0,0}, {0,ca,-sa}, {0,sa,ca}}; final float[][] B = {{cb,sb,0}, {-sb,cb,0}, {0,0,1}}; final float[][] Bi = {{cb,-sb,0}, {sb,cb,0}, {0,0,1}}; final float[][] R = {{c,0,s}, {0,1,0}, {-s,0,c}}; final float[][] S = mxMul(Ai,mxMul(Bi,mxMul(R,mxMul(B,A))));; float[] iPOV = {(float) 0.949, 0,(float) -0.316}; float[] jPOV = {0,(float) 0.97, (float) (-0.243)}; float[] kPOV = {(float) 0.308, (float) 0.231, (float) 0.923}; int boo; Image offScreenImage; Graphics offScreenGraphics; int theHeight, theWidth; float[][] thePoints; int[][] theTriangles; float[][] theOrientations; int[][] screenPoints; boolean[] screenOrientations; Color[] faceColors; final void initFigure() { boo = 1; thePoints = new float[12][3]; screenPoints = new int[12][2]; float sC = (float) (theHeight/4); float rt5 = (float) Math.sqrt(5); float c72 = (float) Math.cos(2.0 * Math.PI / 5.0); float s72 = (float) Math.sin(2.0 * Math.PI / 5.0); float c144 = (float) Math.cos(4.0 * Math.PI / 5.0); float s144 = (float) Math.sin(4.0 * Math.PI / 5.0); thePoints[0][0] = sC; thePoints[0][1] = (float) 0; thePoints[0][2] = (float) 0; thePoints[1][0] = sC / rt5; thePoints[1][1] = sC * 2 / rt5; thePoints[1][2] = (float) 0; thePoints[2][0] = sC / rt5; thePoints[2][1] = sC * c72 * 2 / rt5; thePoints[2][2] = sC * s72 * 2 / rt5; thePoints[3][0] = sC / rt5; thePoints[3][1] = sC * c144 * 2 / rt5; thePoints[3][2] = sC * s144 * 2 / rt5; thePoints[4][0] = sC / rt5; thePoints[4][1] = sC * c144 * 2 / rt5; thePoints[4][2] = - sC * s144 * 2 / rt5; thePoints[5][0] = sC / rt5; thePoints[5][1] = sC * c72 * 2 / rt5; thePoints[5][2] = - sC * s72 * 2 / rt5; // the rest are suitably organized negatives of the above thePoints[6][0] = - sC / rt5; // negative of 3rd thePoints[6][1] = - sC * c144 * 2 / rt5; thePoints[6][2] = - sC * s144 * 2 / rt5; thePoints[7][0] = - sC / rt5; // negative of 4th thePoints[7][1] = - sC * c144 * 2 / rt5; thePoints[7][2] = sC * s144 * 2 / rt5; thePoints[8][0] = - sC / rt5; // negative of 5th thePoints[8][1] = - sC * c72 * 2 / rt5; thePoints[8][2] = sC * s72 * 2 / rt5; thePoints[9][0] = - sC / rt5; // negative of 1st thePoints[9][1] = - sC * 2 / rt5; thePoints[9][2] = (float) 0; thePoints[10][0] = - sC / rt5; // negative of 2nd thePoints[10][1] = - sC * c72 * 2 / rt5; thePoints[10][2] = - sC * s72 * 2 / rt5; thePoints[11][0] = (float) -sC; // negative of 0th thePoints[11][1] = (float) 0; thePoints[11][2] = (float) 0; theTriangles = new int[20][3]; theTriangles[0][0] = 0; theTriangles[0][1] = 1; theTriangles[0][2] = 2; theTriangles[1][0] = 0; theTriangles[1][1] = 2; theTriangles[1][2] = 3; theTriangles[2][0] = 0; theTriangles[2][1] = 3; theTriangles[2][2] = 4; theTriangles[3][0] = 0; theTriangles[3][1] = 4; theTriangles[3][2] = 5; theTriangles[4][0] = 0; theTriangles[4][1] = 5; theTriangles[4][2] = 1; theTriangles[5][0] = 1; theTriangles[5][1] = 7; theTriangles[5][2] = 2; theTriangles[6][0] = 2; theTriangles[6][1] = 8; theTriangles[6][2] = 3; theTriangles[7][0] = 3; theTriangles[7][1] = 9; theTriangles[7][2] = 4; theTriangles[8][0] = 4; theTriangles[8][1] = 10; theTriangles[8][2] = 5; theTriangles[9][0] = 5; theTriangles[9][1] = 6; theTriangles[9][2] = 1; theTriangles[10][0] = 1; theTriangles[10][1] = 6; theTriangles[10][2] = 7; theTriangles[11][0] = 2; theTriangles[11][1] = 7; theTriangles[11][2] = 8; theTriangles[12][0] = 3; theTriangles[12][1] = 8; theTriangles[12][2] = 9; theTriangles[13][0] = 4; theTriangles[13][1] = 9; theTriangles[13][2] = 10; theTriangles[14][0] = 5; theTriangles[14][1] = 10; theTriangles[14][2] = 6; theTriangles[15][0] = 11; theTriangles[15][1] = 10; theTriangles[15][2] = 9; theTriangles[16][0] = 11; theTriangles[16][1] = 9; theTriangles[16][2] = 8; theTriangles[17][0] = 11; theTriangles[17][1] = 8; theTriangles[17][2] = 7; theTriangles[18][0] = 11; theTriangles[18][1] = 7; theTriangles[18][2] = 6; theTriangles[19][0] = 11; theTriangles[19][1] = 6; theTriangles[19][2] = 10; theOrientations = new float[theTriangles.length][3]; screenOrientations = new boolean[theTriangles.length]; for (int i=0; i 0) { screenOrientations[i] = true; } else { screenOrientations[i] = false; } } } final float[] subtractVector(float[] x, float[] y) { float[] out = new float[3]; out[0] = x[0] - y[0]; out[1] = x[1] - y[1]; out[2] = x[2] - y[2]; return out; } final float dot(float[] x, float[] y) { float out = x[0] * y[0] + x[1] * y[1] + x[2] * y[2]; return out; } final float[] cross(float[] x, float[] y) { float[] out = new float[3]; out[0] = x[1] * y[2] - x[2] * y[1]; out[1] = x[2] * y[0] - x[0] * y[2]; out[2] = x[0] * y[1] - x[1] * y[0]; return out; } public void init() { initConstants(); initFigure(); computeScreenD(); repaint(); // query: need this? } final int[] applyPOV(float[] pt) { int[] out = new int[2]; float[] tmp = new float[2]; float scale_factor = 100; tmp[0] = dot(iPOV,pt); tmp[0] /= scale_factor; tmp[1] = dot(jPOV,pt); tmp[1] /= scale_factor; out[0] = theHeight/2 + (int) (((float) theHeight) * tmp[0] * 0.9); out[1] = theHeight/2 - (int) (((float) theHeight) * tmp[1] * 0.9); return out; } final void initConstants() { String url = this.getDocumentBase().toString(); if (url.equals("http://www.math.umn.edu/~garrett/px/RotIcosa.html")) { theHeight = this.size().height; theWidth = this.size().width; } else { theHeight = 15; theWidth = 15; } offScreenImage = createImage(theWidth,theHeight); offScreenGraphics = offScreenImage.getGraphics(); } public void paint(Graphics g) { offScreenGraphics.setColor(backColor); offScreenGraphics.fillRect(0,0,3*theWidth,3*theHeight); drawFigure(offScreenGraphics); g.drawImage(offScreenImage, xSlide, ySlide, this); } public void update(Graphics g) { paint(g); } public void start() { if (th == null) { th = new Thread(this); th.start(); } repaint(); } public void stop() { if (th != null) { th.stop(); try { th.join(); } catch (InterruptedException e) { } th = null; } } void pause(int time) { try { Thread.sleep(time); } catch ( InterruptedException e) { } } public void run() { while (true) { repaint(); rotate(); pause(80); } } final float[][] mxMul(float[][] A, float[][] B) { float[][] out = new float[3][3]; for (int i=0; i<3; i++) { for (int j=0; j<3; j++) { out[i][j] = A[i][0] * B[0][j] + A[i][1] * B[1][j] + A[i][2] * B[2][j]; } } return out; } final void rotate() { float[] iT = new float[3]; float[] jT = new float[3]; float[] kT = new float[3]; for (int i=0; i<3; i++) { iT[i] = R[i][0] * iPOV[0] + R[i][1] * iPOV[1] + R[i][2] * iPOV[2]; jT[i] = R[i][0] * jPOV[0] + R[i][1] * jPOV[1] + R[i][2] * jPOV[2]; kT[i] = R[i][0] * kPOV[0] + R[i][1] * kPOV[1] + R[i][2] * kPOV[2]; } iPOV = iT; jPOV = jT; kPOV = kT; computeScreenD(); repaint(); } public final boolean mouseDown(Event e, int x, int y) { boo++; boo %= 3; return true; } }