import java.awt.*; import java.lang.*; public class Matrix3D { private static int size = 4; private static int vecSize = 3; private float element[]; private float origElement[]; private boolean isLtMult; private StringBuffer trforms; private StringBuffer origTrforms; /////// CONSTRUCTORS ///////////////////////////// // zero argument constructor for future expansion public Matrix3D() { element = new float[size*size]; origElement = new float[size*size]; trforms = new StringBuffer(); origTrforms = new StringBuffer(); loadIdentity(); setToIdentity(origElement); isLtMult = true; //this = newmatrix*this } //NOT TESTED YET // constructor using Matrix3d public Matrix3D( Matrix3D copy) { this.isLtMult = copy.getIsLtMult(); element = new float[size*size]; origElement = new float[size*size]; trforms = new StringBuffer( copy.getTrforms() ); origTrforms = new StringBuffer( copy.getOrigTrforms() ); //COPYING ELEMENT System.arraycopy( copy.getMatArray(), 0, this.element, 0, copy.getMatArray().length ); System.arraycopy( copy.getMatArray(), 0, this.origElement, 0, copy.getMatArray().length ); } public Matrix3D( Raster r) { int width = r.getWidth(); int height = r.getHeight(); element = new float[size*size]; origElement = new float[size*size]; trforms = new StringBuffer(); origTrforms = new StringBuffer(); loadIdentity(); isLtMult = false; //CANONICAL TO RASTER TRANSFROMATION IS USED TO INITIALIZE //RIGHT MULTIPLICATION REQD LATER ON //RIGHT = TOP = NEAR = 1; LEFT=BOTTOM=FAR=-1 float zmax = width; element[index(0,0)] = width/2.0f ; element[index(0,3)] = width/2.0f ; element[index(1,1)] = height/(-2.0f) ; element[index(1,3)] = height/2.0f ; element[index(2,2)] = -zmax/2.0f ; element[index(2,3)] = zmax/2.0f ; System.arraycopy( this.element, 0, this.origElement, 0, this.element.length ); // System.out.println("PRINTING CANONICAL-DISPLAY TRANS "); // printMatrix3D( element ); } ///////// TRANSFORM METHODS //////////////////////////// public final void loadIdentity(){ for( int i=0; i 1) { pix = (int) Long.parseLong(st.sval.substring(1), 8); } else pix = Integer.parseInt(st.sval); return pix; } public void ReadInput(InputStream is) throws IOException { Reader r = new BufferedReader(new InputStreamReader(is)); StreamTokenizer st = new StreamTokenizer(r); configureParser(st); scan: while (true) { switch (st.nextToken()) { default: break scan; case StreamTokenizer.TT_WORD: if (st.sval.equals("c")) { float x = (float) getNumber(st); float y = (float) getNumber(st); float z = (float) getNumber(st); //int clr = getColor(st); int clr = (int) getNumber(st) ; if (axesVtcs == axesList.length) { Point3D newList[] = new Point3D[vertList.length+CHUNKSIZE]; System.arraycopy(axesList, 0, newList, 0, axesList.length); axesList = newList; } axesList[axesVtcs++] = new Point3D(x, y, z, 1, clr); } else if (st.sval.equals("v")) { float x = (float) getNumber(st); float y = (float) getNumber(st); float z = (float) getNumber(st); //int clr = getColor(st); int clr = (int) getNumber(st) ; if (vertices == vertList.length) { Point3D newList[] = new Point3D[vertList.length+CHUNKSIZE]; System.arraycopy(vertList, 0, newList, 0, vertList.length); vertList = newList; } vertList[vertices++] = new Point3D(x, y, z, 1, clr); } else if (st.sval.equals("eye")) { eyex = (float) getNumber(st); eyey = (float) getNumber(st); eyez = (float) getNumber(st); } else if (st.sval.equals("look")) { lookatx = (float) getNumber(st); lookaty = (float) getNumber(st); lookatz = (float) getNumber(st); } else if (st.sval.equals("up")) { upx = (float) getNumber(st); upy = (float) getNumber(st); upz = (float) getNumber(st); } else if (st.sval.equals("fov")) { fov = (float) getNumber(st); } else { System.err.println("ERROR: line "+st.lineno()+": unexpected token :"+st.sval); break scan; } break; } //if (vertices % 100 == 0)showStatus("vertices = " + (vertices+1)); showStatus("vertices = " + vertices); } is.close(); if (st.ttype != StreamTokenizer.TT_EOF) { throw new IOException(st.toString()); } } public void paint(Graphics g) { g.drawImage(screen, 0, 0, this); } public void update(Graphics g) { paint(g); } public void setViewLine(float eyex,float eyey, float eyez, float lookatx, float lookaty, float lookatz, float upx, float upy, float upz) { view.lookAt(eyex, eyey, eyez, lookatx, lookaty, lookatz, upx, upy, upz); axesView.lookAt(eyex, eyey, eyez, lookatx, lookaty, lookatz, upx, upy, upz); } float v0x, v0y, v0z; int state=0; public void mousePressed( MouseEvent e ) { int x=e.getX(); int y=e.getY(); if (e.isMetaDown()) { showStatus("Resetting model matrix"); model.loadIdentity(); } v0x = (float) (x - (getSize().width / 2)); v0y = (float) ((getSize().height / 2) - y); v0z = (float) getSize().width; float l0 = (float) (1 / Math.sqrt(v0x*v0x + v0y*v0y + v0z*v0z)); v0x *= l0; v0y *= l0; v0z *= l0; state=0; showStatus("Rotation about any axis"); return; } public void mouseReleased( MouseEvent e ) { ; } public void mouseEntered( MouseEvent e ) { ; } public void mouseExited( MouseEvent e ) { ;} public void mouseClicked( MouseEvent e ) { ; } public void mouseDragged( MouseEvent e) { int x=e.getX(); int y=e.getY(); if (e.isMetaDown()) { showStatus("Resetting model matrix"); } else { float v1x = (float) (x - (getSize().width / 2)); float v1y = (float) ((getSize().height / 2) - y); float v1z = (float) getSize().width; float l = (float) (1 / Math.sqrt(v1x*v1x + v1y*v1y + v1z*v1z)); v1x *= l; v1y *= l; v1z *= l; float ax = v0y*v1z - v0z*v1y; float ay = v0z*v1x - v0x*v1z; float az = v0x*v1y - v0y*v1x; l = (float) Math.sqrt(ax*ax + ay*ay + az*az); float theta = (float) Math.asin(l); if (v0x*v1x + v0y*v1y + v0z*v1z < 0) theta += (float) Math.PI / 2; model.rotate(ax, ay, az, theta); v0x = v1x; v0y = v1y; v0z = v1z; model.transform(vertList, worldList, 0, vertices); view.transform(worldList, tranList, 0, vertices); DrawObject(); } screen = raster.toImage(this); repaint(); return; } public void mouseMoved( MouseEvent e ) { ; } void DrawObject(){ int ix, iy; float iz, iw; int w, h; w = raster.getWidth(); h = raster.getHeight(); raster.fill(getBackground()); for (int i = 0; i < axesVtcs; i++) { if( tranAxesList[i].getCoord(3) !=0){ ix = (int) (tranAxesList[i].getCoord(0) / tranAxesList[i].getCoord(3)); iy = (int) (tranAxesList[i].getCoord(1) / tranAxesList[i].getCoord(3)); iz = tranAxesList[i].getCoord(2) /tranAxesList[i].getCoord(3) ; iw = tranAxesList[i].getCoord(3) /tranAxesList[i].getCoord(3) ; if (ix >= 0 && iy >= 0 && ix < w && iy < h){ raster.setPixel(axesList[i].getColor(), ix, iy); } } } int nRendered = 0; for (int i = 0; i < vertices; i++) { if( tranList[i].getCoord(3) !=0){ ix = (int) (tranList[i].getCoord(0) / tranList[i].getCoord(3)); iy = (int) (tranList[i].getCoord(1) / tranList[i].getCoord(3)); iz = tranList[i].getCoord(2) /tranList[i].getCoord(3) ; iw = tranList[i].getCoord(3) /tranList[i].getCoord(3) ; if (ix >= 0 && iy >= 0 && ix < w && iy < h){ nRendered++; raster.setPixel(vertList[i].getColor(), ix, iy); } } } showStatus("Vertices rendered = " + nRendered ); showStatus("PercentNOT rendered = " + (vertices-nRendered)*100/vertices ); } } ********************************************************************************