/* * cube.java * * Created on 31 December 2003, 12:06 */ import java.awt.*; import java.awt.image.*; import java.awt.color.*; /** * * @author Allen */ public class cube extends java.awt.Frame { // sin cosine lookup table, should be faster than doing the maths! private double[][] lookup = {{0.000000, 1.000000}, {0.017452, 0.999848}, {0.034899, 0.999391}, {0.052336, 0.998630}, {0.069756, 0.997564}, {0.087156, 0.996195}, {0.104528, 0.994522}, {0.121869, 0.992546}, {0.139173, 0.990268}, {0.156434, 0.987688}, {0.173648, 0.984808}, {0.190809, 0.981627}, {0.207912, 0.978148}, {0.224951, 0.974370}, {0.241922, 0.970296}, {0.258819, 0.965926}, {0.275637, 0.961262}, {0.292372, 0.956305}, {0.309017, 0.951057}, {0.325568, 0.945519}, {0.342020, 0.939693}, {0.358368, 0.933580}, {0.374607, 0.927184}, {0.390731, 0.920505}, {0.406737, 0.913545}, {0.422618, 0.906308}, {0.438371, 0.898794}, {0.453990, 0.891007}, {0.469472, 0.882948}, {0.484810, 0.874620}, {0.500000, 0.866025}, {0.515038, 0.857167}, {0.529919, 0.848048}, {0.544639, 0.838671}, {0.559193, 0.829038}, {0.573576, 0.819152}, {0.587785, 0.809017}, {0.601815, 0.798636}, {0.615661, 0.788011}, {0.629320, 0.777146}, {0.642788, 0.766044}, {0.656059, 0.754710}, {0.669131, 0.743145}, {0.681998, 0.731354}, {0.694658, 0.719340}, {0.707107, 0.707107}, {0.719340, 0.694658}, {0.731354, 0.681998}, {0.743145, 0.669131}, {0.754710, 0.656059}, {0.766044, 0.642788}, {0.777146, 0.629320}, {0.788011, 0.615661}, {0.798636, 0.601815}, {0.809017, 0.587785}, {0.819152, 0.573576}, {0.829038, 0.559193}, {0.838671, 0.544639}, {0.848048, 0.529919}, {0.857167, 0.515038}, {0.866025, 0.500000}, {0.874620, 0.484810}, {0.882948, 0.469472}, {0.891007, 0.453990}, {0.898794, 0.438371}, {0.906308, 0.422618}, {0.913545, 0.406737}, {0.920505, 0.390731}, {0.927184, 0.374607}, {0.933580, 0.358368}, {0.939693, 0.342020}, {0.945519, 0.325568}, {0.951057, 0.309017}, {0.956305, 0.292372}, {0.961262, 0.275637}, {0.965926, 0.258819}, {0.970296, 0.241922}, {0.974370, 0.224951}, {0.978148, 0.207912}, {0.981627, 0.190809}, {0.984808, 0.173648}, {0.987688, 0.156434}, {0.990268, 0.139173}, {0.992546, 0.121869}, {0.994522, 0.104528}, {0.996195, 0.087156}, {0.997564, 0.069756}, {0.998630, 0.052336}, {0.999391, 0.034899}, {0.999848, 0.017452}, {1.000000, -0.000000}, {0.999848, -0.017452}, {0.999391, -0.034899}, {0.998630, -0.052336}, {0.997564, -0.069756}, {0.996195, -0.087156}, {0.994522, -0.104528}, {0.992546, -0.121869}, {0.990268, -0.139173}, {0.987688, -0.156434}, {0.984808, -0.173648}, {0.981627, -0.190809}, {0.978148, -0.207912}, {0.974370, -0.224951}, {0.970296, -0.241922}, {0.965926, -0.258819}, {0.961262, -0.275637}, {0.956305, -0.292372}, {0.951057, -0.309017}, {0.945519, -0.325568}, {0.939693, -0.342020}, {0.933580, -0.358368}, {0.927184, -0.374607}, {0.920505, -0.390731}, {0.913545, -0.406737}, {0.906308, -0.422618}, {0.898794, -0.438371}, {0.891007, -0.453990}, {0.882948, -0.469472}, {0.874620, -0.484810}, {0.866025, -0.500000}, {0.857167, -0.515038}, {0.848048, -0.529919}, {0.838671, -0.544639}, {0.829038, -0.559193}, {0.819152, -0.573576}, {0.809017, -0.587785}, {0.798636, -0.601815}, {0.788011, -0.615661}, {0.777146, -0.629320}, {0.766044, -0.642788}, {0.754710, -0.656059}, {0.743145, -0.669131}, {0.731354, -0.681998}, {0.719340, -0.694658}, {0.707107, -0.707107}, {0.694658, -0.719340}, {0.681998, -0.731354}, {0.669131, -0.743145}, {0.656059, -0.754710}, {0.642788, -0.766044}, {0.629320, -0.777146}, {0.615661, -0.788011}, {0.601815, -0.798636}, {0.587785, -0.809017}, {0.573576, -0.819152}, {0.559193, -0.829038}, {0.544639, -0.838671}, {0.529919, -0.848048}, {0.515038, -0.857167}, {0.500000, -0.866025}, {0.484810, -0.874620}, {0.469472, -0.882948}, {0.453990, -0.891007}, {0.438371, -0.898794}, {0.422618, -0.906308}, {0.406737, -0.913545}, {0.390731, -0.920505}, {0.374607, -0.927184}, {0.358368, -0.933580}, {0.342020, -0.939693}, {0.325568, -0.945519}, {0.309017, -0.951057}, {0.292372, -0.956305}, {0.275637, -0.961262}, {0.258819, -0.965926}, {0.241922, -0.970296}, {0.224951, -0.974370}, {0.207912, -0.978148}, {0.190809, -0.981627}, {0.173648, -0.984808}, {0.156434, -0.987688}, {0.139173, -0.990268}, {0.121869, -0.992546}, {0.104528, -0.994522}, {0.087156, -0.996195}, {0.069756, -0.997564}, {0.052336, -0.998630}, {0.034899, -0.999391}, {0.017452, -0.999848}, {-0.000000, -1.000000}, {-0.017452, -0.999848}, {-0.034899, -0.999391}, {-0.052336, -0.998630}, {-0.069756, -0.997564}, {-0.087156, -0.996195}, {-0.104528, -0.994522}, {-0.121869, -0.992546}, {-0.139173, -0.990268}, {-0.156434, -0.987688}, {-0.173648, -0.984808}, {-0.190809, -0.981627}, {-0.207912, -0.978148}, {-0.224951, -0.974370}, {-0.241922, -0.970296}, {-0.258819, -0.965926}, {-0.275637, -0.961262}, {-0.292372, -0.956305}, {-0.309017, -0.951057}, {-0.325568, -0.945519}, {-0.342020, -0.939693}, {-0.358368, -0.933580}, {-0.374607, -0.927184}, {-0.390731, -0.920505}, {-0.406737, -0.913545}, {-0.422618, -0.906308}, {-0.438371, -0.898794}, {-0.453991, -0.891007}, {-0.469472, -0.882948}, {-0.484810, -0.874620}, {-0.500000, -0.866025}, {-0.515038, -0.857167}, {-0.529919, -0.848048}, {-0.544639, -0.838671}, {-0.559193, -0.829038}, {-0.573576, -0.819152}, {-0.587785, -0.809017}, {-0.601815, -0.798636}, {-0.615661, -0.788011}, {-0.629320, -0.777146}, {-0.642788, -0.766044}, {-0.656059, -0.754710}, {-0.669131, -0.743145}, {-0.681998, -0.731354}, {-0.694658, -0.719340}, {-0.707107, -0.707107}, {-0.719340, -0.694658}, {-0.731354, -0.681998}, {-0.743145, -0.669131}, {-0.754710, -0.656059}, {-0.766044, -0.642788}, {-0.777146, -0.629320}, {-0.788011, -0.615661}, {-0.798636, -0.601815}, {-0.809017, -0.587785}, {-0.819152, -0.573576}, {-0.829038, -0.559193}, {-0.838671, -0.544639}, {-0.848048, -0.529919}, {-0.857167, -0.515038}, {-0.866025, -0.500000}, {-0.874620, -0.484810}, {-0.882948, -0.469472}, {-0.891007, -0.453990}, {-0.898794, -0.438371}, {-0.906308, -0.422618}, {-0.913545, -0.406737}, {-0.920505, -0.390731}, {-0.927184, -0.374607}, {-0.933580, -0.358368}, {-0.939693, -0.342020}, {-0.945519, -0.325568}, {-0.951057, -0.309017}, {-0.956305, -0.292372}, {-0.961262, -0.275637}, {-0.965926, -0.258819}, {-0.970296, -0.241922}, {-0.974370, -0.224951}, {-0.978148, -0.207912}, {-0.981627, -0.190809}, {-0.984808, -0.173648}, {-0.987688, -0.156434}, {-0.990268, -0.139173}, {-0.992546, -0.121869}, {-0.994522, -0.104528}, {-0.996195, -0.087156}, {-0.997564, -0.069756}, {-0.998630, -0.052336}, {-0.999391, -0.034899}, {-0.999848, -0.017452}, {-1.000000, 0.000000}, {-0.999848, 0.017452}, {-0.999391, 0.034899}, {-0.998630, 0.052336}, {-0.997564, 0.069756}, {-0.996195, 0.087156}, {-0.994522, 0.104528}, {-0.992546, 0.121869}, {-0.990268, 0.139173}, {-0.987688, 0.156434}, {-0.984808, 0.173648}, {-0.981627, 0.190809}, {-0.978148, 0.207912}, {-0.974370, 0.224951}, {-0.970296, 0.241922}, {-0.965926, 0.258819}, {-0.961262, 0.275637}, {-0.956305, 0.292372}, {-0.951057, 0.309017}, {-0.945519, 0.325568}, {-0.939693, 0.342020}, {-0.933580, 0.358368}, {-0.927184, 0.374607}, {-0.920505, 0.390731}, {-0.913545, 0.406737}, {-0.906308, 0.422618}, {-0.898794, 0.438371}, {-0.891007, 0.453991}, {-0.882948, 0.469472}, {-0.874620, 0.484810}, {-0.866025, 0.500000}, {-0.857167, 0.515038}, {-0.848048, 0.529919}, {-0.838671, 0.544639}, {-0.829038, 0.559193}, {-0.819152, 0.573576}, {-0.809017, 0.587785}, {-0.798636, 0.601815}, {-0.788011, 0.615661}, {-0.777146, 0.629320}, {-0.766044, 0.642788}, {-0.754710, 0.656059}, {-0.743145, 0.669131}, {-0.731354, 0.681998}, {-0.719340, 0.694658}, {-0.707107, 0.707107}, {-0.694658, 0.719340}, {-0.681998, 0.731354}, {-0.669131, 0.743145}, {-0.656059, 0.754710}, {-0.642788, 0.766044}, {-0.629320, 0.777146}, {-0.615661, 0.788011}, {-0.601815, 0.798636}, {-0.587785, 0.809017}, {-0.573576, 0.819152}, {-0.559193, 0.829038}, {-0.544639, 0.838671}, {-0.529919, 0.848048}, {-0.515038, 0.857167}, {-0.500000, 0.866025}, {-0.484810, 0.874620}, {-0.469472, 0.882948}, {-0.453990, 0.891007}, {-0.438371, 0.898794}, {-0.422618, 0.906308}, {-0.406737, 0.913545}, {-0.390731, 0.920505}, {-0.374607, 0.927184}, {-0.358368, 0.933580}, {-0.342020, 0.939693}, {-0.325568, 0.945519}, {-0.309017, 0.951057}, {-0.292372, 0.956305}, {-0.275637, 0.961262}, {-0.258819, 0.965926}, {-0.241922, 0.970296}, {-0.224951, 0.974370}, {-0.207912, 0.978148}, {-0.190809, 0.981627}, {-0.173648, 0.984808}, {-0.156434, 0.987688}, {-0.139173, 0.990268}, {-0.121869, 0.992546}, {-0.104528, 0.994522}, {-0.087156, 0.996195}, {-0.069756, 0.997564}, {-0.052336, 0.998630}, {-0.034899, 0.999391}, {-0.017452, 0.999848}}; private static class myPoint { double x; double y; double z; } private final static int Z_OFF_SET = 256; // must be final static for use to dimension arrays ! private final static int MaxLines = 12; // must be final static for use to dimension arrays ! private final static boolean SHOW_FRAME_TIME = false; // show frame time or fps // 3D co-ords (X1,Y1,Z1)(X2,Y2,Z2) for two ends of a line private static int[] Obj = {-10,-10,-10,10,-10,-10,-10,-10,-10,-10,10,-10, -10,10,-10,10,10,-10,10,-10,-10,10,10,-10, -10,-10,10,10,-10,10,-10,-10,10,-10,10,10, -10,10,10,10,10,10,10,-10,10,10,10,10, -10,-10,10,-10,-10,-10,-10,10,10,-10,10,-10, 10,10,10,10,10,-10,10,-10,10,10,-10,-10}; private static myPoint[][] Lines = new myPoint[MaxLines][2]; private static myPoint[][] translated = new myPoint[MaxLines][2]; private static myPoint[][] Oldtranslated = new myPoint[MaxLines][2]; private static int[] OldLines = new int[MaxLines*4]; /* used for XDrawLine */ private static int[] NewLines = new int[MaxLines*4]; private static int xoff, yoff, zoff; private static int NUM_X_PIXELS = 320; private static int NUM_Y_PIXELS = 240; private final static int SLEEP_TIME = 20; // period of thread sleep in ms private static int FRAMES_TO_CHECK = 100; // how many frames to average the frame time over private static int width = NUM_X_PIXELS; // why am I doing this ! private static int height = NUM_Y_PIXELS; private static int[] fullRGBPalette = new int[256]; private static long frameTime, timeTemp; private static int frameCount = 0; private static float fps = (float)0.0; private static BufferedImage img; private static Graphics g; /** Creates new form cube */ public cube() { int loop; int xdeg, ydeg, zdeg; initComponents(); // set the number of frames to do the timing over (aim for 2 second update based on sleep time) FRAMES_TO_CHECK = 2000 / SLEEP_TIME; setTitle("Cube"); setSize(width, height); setVisible(true); setBackground(Color.black); img = new BufferedImage(width, height, ColorSpace.TYPE_RGB); for(loop = 0; loop < MaxLines; loop++) { Lines [loop][0] = new myPoint(); Lines [loop][1] = new myPoint(); translated [loop][0] = new myPoint(); translated [loop][1] = new myPoint(); Oldtranslated [loop][0] = new myPoint(); Oldtranslated [loop][1] = new myPoint(); Lines [loop][0].x = (double)Obj [((loop + 1) * 6) - 6]; Lines [loop][0].y = (double)Obj [((loop + 1) * 6) - 5]; Lines [loop][0].z = (double)Obj [((loop + 1) * 6) - 4]; Lines [loop][1].x = (double)Obj [((loop + 1) * 6) - 3]; Lines [loop][1].y = (double)Obj [((loop + 1) * 6) - 2]; Lines [loop][1].z = (double)Obj [((loop + 1) * 6) - 1]; translated[loop][0].x = (double)0.0; translated[loop][0].y = (double)0.0; translated[loop][0].z = (double)0.0; translated[loop][1].x = (double)0.0; translated[loop][1].y = (double)0.0; translated[loop][1].z = (double)0.0; } xoff=NUM_X_PIXELS/2; yoff=NUM_Y_PIXELS/2; zoff=Z_OFF_SET; g = this.getGraphics(); timeTemp = System.currentTimeMillis(); xdeg = ydeg = zdeg = 0; for (loop=-256;loop<=-100;loop++) { zoff = loop; RotatePoints(xdeg,ydeg,zdeg); DrawPoints(1); xdeg++; ydeg++; zdeg++; if(xdeg==360) xdeg=0; if(ydeg==360) ydeg=0; if(zdeg==360) zdeg=0; try { Thread.sleep(SLEEP_TIME); } catch (Exception e) {} } for(;;) { // Calculate new positions RotatePoints(xdeg,ydeg,zdeg); DrawPoints(0); xdeg++; ydeg++; zdeg++; if(xdeg==360) xdeg=0; if(ydeg==360) ydeg=0; if(zdeg==360) zdeg=0; try { Thread.sleep(SLEEP_TIME); } catch (Exception e) {} repaint(); } } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ private void initComponents() {//GEN-BEGIN:initComponents addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { exitForm(evt); } }); pack(); }//GEN-END:initComponents /** Exit the Application */ private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm System.exit(0); }//GEN-LAST:event_exitForm /** * @param args the command line arguments */ public static void main(String args[]) { new cube().show(); } public void paint(Graphics g) { int loop, x, y; g.setColor(Color.black); frameCount++; if(SHOW_FRAME_TIME) { // clear old text g.drawString("Frame time: "+ (((float)frameTime / FRAMES_TO_CHECK) - SLEEP_TIME) +" ms (+ " + SLEEP_TIME + "ms)", 10, height - 10); if(frameCount > FRAMES_TO_CHECK) { frameCount = 0; frameTime = System.currentTimeMillis() - timeTemp; timeTemp = System.currentTimeMillis(); } g.setColor(Color.white); g.drawString("Frame time: "+ (((float)frameTime / FRAMES_TO_CHECK) - SLEEP_TIME) +" ms (+ " + SLEEP_TIME + "ms)", 10, height - 10); } else { g.drawString("FPS: "+ fps, 10, height - 10); if(System.currentTimeMillis() > timeTemp + 2000) { // check fps every two secs frameTime = System.currentTimeMillis() - timeTemp; fps = (float)frameCount / frameTime * 1000; frameCount = 0; timeTemp = System.currentTimeMillis(); } g.setColor(Color.white); g.drawString("FPS: "+ fps, 10, height - 10); } } public void update(Graphics g) { paint(g); } // Procedure RotatePoints (X,Y,Z:Integer); // { This rotates object lines by X,Y and Z; then places the result in // TRANSLATED } // rotate about x: newy = cos*y-sin*z (cos*cos-sin*sin) // newz = sin*y+cos*z (sin*cos+cos*sin) // i.e: newy+i*newz=e^(i*theta)*(y+i*z) (theta=int x) // =(cos+i*sin)*(y+i*z) // translated[loop1][0] and translated[loop1][1] are the two endpoints // of line segment loop1. private void RotatePoints(int x, int y, int z) { int loop1; myPoint temp = new myPoint(); for(loop1=0;loop1 0) { temp.x = (lookup[y][1] * translated[loop1][0].x) + (lookup[y][0] * translated[loop1][0].z); temp.y = translated[loop1][0].y; temp.z = ((-lookup[y][0]) * translated[loop1][0].x) + (lookup[y][1] * translated[loop1][0].z); translated[loop1][0].x = temp.x; translated[loop1][0].y = temp.y; translated[loop1][0].z = temp.z; } if(z > 0) { temp.x = (lookup[z][1] * translated[loop1][0].x) - (lookup[z][0] * translated[loop1][0].y); temp.y = (lookup[z][0] * translated[loop1][0].x) + (lookup[z][1] * translated[loop1][0].y); temp.z = translated[loop1][0].z; translated[loop1][0].x = temp.x; translated[loop1][0].y = temp.y; translated[loop1][0].z = temp.z; } // End point of line temp.x = Lines[loop1][1].x; temp.y = (lookup[x][1] * Lines[loop1][1].y) - (lookup[x][0]*Lines[loop1][1].z); temp.z = (lookup[x][0] * Lines[loop1][1].y) + (lookup[x][1] * Lines[loop1][1].z); translated[loop1][1].x = temp.x; translated[loop1][1].y = temp.y; translated[loop1][1].z = temp.z; if(y > 0) { temp.x = (lookup[y][1] * translated[loop1][1].x) + (lookup[y][0] * translated[loop1][1].z); temp.y = translated[loop1][1].y; temp.z = ((-lookup[y][0]) * translated[loop1][1].x) + (lookup[y][1] * translated[loop1][1].z); translated[loop1][1].x = temp.x; translated[loop1][1].y = temp.y; translated[loop1][1].z = temp.z; } if(z > 0) { temp.x = (lookup[z][1] * translated[loop1][1].x) - (lookup[z][0] * translated[loop1][1].y); temp.y = (lookup[z][0] * translated[loop1][1].x) + (lookup[z][1] * translated[loop1][1].y); temp.z = translated[loop1][1].z; translated[loop1][1].x = temp.x; translated[loop1][1].y = temp.y; translated[loop1][1].z = temp.z; } } } // Procedure DrawPoints; // This draws the translated object private void DrawPoints(int moved_z) { int loop1; int nx,ny,nx2,ny2; int temp, temp1, temp2; int t_colour; for(loop1=0;loop1 0) && (nx < NUM_X_PIXELS) && (ny > 0) && (ny < NUM_Y_PIXELS) && (nx2 > 0) && (nx2 < NUM_X_PIXELS) && (ny2 > 0) && (ny2 < NUM_Y_PIXELS)) g.drawLine(nx,ny,nx2,ny2); } // draw new line g.setColor(Color.white); if(((translated[loop1][0].z + zoff) < 0) && ((translated[loop1][1].z + zoff) < 0)) { // greyscale by Z (unless the object is very large you won't notice much! // unless it gets translated through the Z axis) based on lines average Z value. t_colour = (int)((translated[loop1][0].z + zoff) + (translated[loop1][1].z + zoff)) / 2; if(t_colour > 0) { t_colour = 0; } if(t_colour < -255) { t_colour = -255; } t_colour = t_colour + 256; g.setColor(new Color(t_colour, t_colour, t_colour)); // start point of line temp = (int)(translated[loop1][0].z + zoff); nx = (int)((256 * translated[loop1][0].x) / temp) + xoff; ny = (int)((256 * translated[loop1][0].y) / temp) + yoff; // end point of line temp = (int)(translated[loop1][1].z + zoff); nx2 = (int)((256 * translated[loop1][1].x) / temp) + xoff; ny2 = (int)((256 * translated[loop1][1].y) / temp) + yoff; // check bounds if((nx > -1) && (nx < NUM_X_PIXELS) && (ny > -1) && (ny < NUM_Y_PIXELS) && (nx2 > -1) && (nx2 < NUM_X_PIXELS) && (ny2 > -1) && (ny2 < NUM_Y_PIXELS)) g.drawLine(nx,ny,nx2,ny2); else System.out.println("nx or ny out of bounds"); } else System.out.println("Z out of bounds"); } } // Variables declaration - do not modify//GEN-BEGIN:variables // End of variables declaration//GEN-END:variables }