/* Simple 3D graphics routines - academic use only - by Chuck Liang, Hofstra University Computer Science */ import java.awt.*; import java.awt.Graphics; class point3 { public int x; public int y; public int z; public point3(int a, int b, int c) {x=a; y=b; z=c;} } public class boxworld { public int XDIM = 800; public int YDIM = 600; public int ZDIM = 400; // zoom ratio - right now, not tied to ZDIM, but probably should! private double ZR = 0.5; private double tiltR = Math.PI/2; // tilt angle in radians // shortening ratio (scales z axis): usually should set to one: private double SR = 1.0; public final int xshift; // static display shift values public final int yshift; public void SR(double s) {SR = s;} public void ZR(double z) {ZR=z;} public void tilt(int d) {tiltR=Math.toRadians(d);} public boxworld(int xd, int yd, int zd, double zr0, int trd) { XDIM=xd; YDIM=yd; ZDIM=zd; ZR=zr0; tiltR = Math.toRadians(trd); xshift = (int)(ZDIM * Math.cos(tiltR) * SR); yshift = (int)(ZDIM * Math.sin(tiltR) * SR); } public boxworld(int xd, int yd, int zd, double zr0, int trd, double sr0) { XDIM=xd; YDIM=yd; ZDIM=zd; ZR=zr0; tiltR = Math.toRadians(trd); SR = sr0; xshift = (int)(ZDIM * Math.cos(tiltR) * SR); yshift = (int)(ZDIM * Math.sin(tiltR) * SR); } // critical function to convert 3d coordinate to 2d coordinate public Point point32(int x, int y, int z) { double s; int x2; int y2; s = (1-((1-ZR)*(double)z/((double)ZDIM))); x2 = (int) ((s*x) + (z * Math.cos(tiltR) * SR)); y2 = (int) ((s*y) + (z * Math.sin(tiltR) * SR)); y2 += 30 + Math.abs(yshift); if(xshift<0) x2 -= (int)xshift; x2 += 10; return new Point(x2,y2); } // point32 public void drawbox(Graphics brush, int x0, int y0, int z0, int xd, int yd, int zd, Color mc) { int a, b, u, v, x, y, p, q; Point ab, xy, uv, pq; brush.setColor(mc); ab = point32(x0,y0,z0); xy = point32(x0+xd,y0,z0); uv = point32(x0,y0+yd,z0); pq = point32(x0+xd,y0+yd,z0); a = ab.x; b = ab.y; x = xy.x; y= xy.y; u = uv.x; v = uv.y; p = pq.x; q=pq.y; // front brush.drawLine(a,b,x,y); brush.drawLine(a,b,u,v); brush.drawLine(u,v,p,q); brush.drawLine(p,q,x,y); // sides xy = point32(x0,y0,z0+zd); pq = point32(x0,y0+yd,z0+zd); brush.drawLine(a,b,xy.x,xy.y); brush.drawLine(u,v,pq.x,pq.y); brush.drawLine(xy.x,xy.y,pq.x,pq.y); ab = point32(x0+xd,y0,z0+zd); uv = point32(x0+xd,y0+yd,z0+zd); brush.drawLine(xy.x,xy.y,ab.x,ab.y); brush.drawLine(pq.x,pq.y,uv.x,uv.y); brush.drawLine(ab.x,ab.y,uv.x,uv.y); xy = point32(x0+xd,y0,z0); pq = point32(x0+xd,y0+yd,z0); brush.drawLine(ab.x,ab.y,xy.x,xy.y); brush.drawLine(uv.x,uv.y,pq.x,pq.y); } //drawbox public void drawline(Graphics brush, int x0, int y0, int z0, int x1, int y1, int z1, Color mc) { Point ab = point32(x0,y0,z0); Point xy = point32(x1,y1,z1); brush.setColor(mc); brush.drawLine(ab.x,ab.y,xy.x,xy.y); } // fill circle with scaled radius public void fillcircle(Graphics brush, int x0, int y0, int z0, double r, Color mc) { int x, y, rs; Point xy = point32(x0,y0,z0); x = xy.x; y=xy.y; rs = (int) ((1-((1-ZR)*((double)z0)/ZDIM)) * r); if (rs<1) rs = 1; // radius can't be too small. brush.setColor(mc); brush.fillOval(x-rs,y-rs,2*rs,2*rs); // MPE_Draw_circle(graph,x,y,(int)rs-2,MPE_BLACK); // 3d effect? } // draw circle with scaled radius public void drawcircle(Graphics brush, int x0, int y0, int z0, double r, Color mc) { int x, y, rs; Point xy = point32(x0,y0,z0); x = xy.x; y=xy.y; rs = (int) ((1-((1-ZR)*((double)z0)/ZDIM)) * r); if (rs<1) rs = 1; // radius can't be too small. brush.setColor(mc); brush.drawOval(x-rs,y-rs,2*rs,2*rs); // MPE_Draw_circle(graph,x,y,(int)rs-2,MPE_BLACK); // 3d effect? } // draw image to scale - w and h represent the original dimensions of the // image public void drawimage(Graphics brush, Image im, int x, int y, int z, int w, int h) { int ws, hs; Point xy = point32(x,y,z); ws = (int)dscale(w,z); hs = (int)dscale(h,z); brush.drawImage(im,xy.x,xy.y,ws,hs,null); } public void drawimage(Graphics brush, Image im, int x, int y, int z) { int w, h, ws, hs; Point xy = point32(x,y,z); w = im.getWidth(null); h = im.getHeight(null); ws = (int)dscale(w,z); hs = (int)dscale(h,z); brush.drawImage(im,xy.x,xy.y,ws,hs,null); } // scale size x based on z coordinate z0: public double dscale(double x, double z0) { return (1-((1-ZR)*((double)z0)/ZDIM)) * x; } /* monte carlo method public void drawmc(Graphics brush, int i, montecarlo mtc,Color mc) { double x, y, z; int a, b, c; for (;i>0;i--) { x = (Math.random() * XDIM) - (XDIM/2); y = (Math.random() * YDIM) - (YDIM/2); z = (Math.random() * ZDIM) - (ZDIM/2); a = (int) (x+ (XDIM/2)); b = (int) (y+ (YDIM/2)); c = (int) (z+ (ZDIM/2)); if (mtc.p(x,y,z)) fillcircle(brush,a,b,c,2.0,mc); } } // drawmc */ // suggested window width and height public int wwidth() { return XDIM+Math.abs(xshift)+20;} public int wheight() { return YDIM+Math.abs(yshift)+40;} }// boxworld