import java.applet.*; import java.awt.*; import java.io.*; import java.net.URL; import java.util.StringTokenizer; import java.util.Vector; import java.util.Hashtable; public class ZbufSurf extends Applet{ Dimension appsize; Panel p1 = new Panel(); Panel p2 = new Panel(); Panel p3 = new Panel(); Panel p4 = new Panel(); String datafile; TextField t1, t2, t3, t4; Label l1, l2, l3, l4, l5,l6; Button b1, b2, b3; Choice c = new Choice(); ZbufCanvas zCanvas; BezierApplet3 Bezier; double scale = 30; CheckboxGroup chkgrp; int bezdat; int jnum; public void init() { setBackground(Color.black); setForeground(Color.red); setLayout(new BorderLayout(0,0)); appsize = size(); //p1に項目の追加 p1.setBackground(new Color(40,40,125)); p1.setForeground(Color.white); //jie.color p1.add(l3 = new Label("R:")); p1.add(t3 = new TextField("500",3)); p1.add(l1 = new Label("Theta:")); p1.add(t1 = new TextField("20",3)); p1.add(l2 = new Label("Phi:")); p1.add(t2 = new TextField("30",3)); //cに項目の追加 c.addItem("Squear"); c.addItem("BezCurve"); c.addItem("Monitor"); c.addItem("3D_N"); c.addItem("Bezball"); c.addItem("Bezball2"); c.addItem("Teapot"); c.addItem("Edit"); //p2に項目の追加 p2.setBackground(new Color(40,40,120)); p2.setForeground(Color.red); p2.add(l4 = new Label("Data:")); p2.add(c); p2.add(b2 = new Button("Read")); p2.add(b1 = new Button("ReDraw")); p2.add(b3 = new Button("Bezi")); //c2に項目の追加 chkgrp = new CheckboxGroup(); Checkbox chk1 = new Checkbox("Shading",chkgrp,true); Checkbox chk2 = new Checkbox("Drawing",chkgrp,false); //p3に項目の追加 p3.setBackground(new Color(50,30,120)); //nis12 p3.setForeground(Color.white);//jie.color p3.add(l6 = new Label("Mode:")); p3.add(chk1); p3.add(chk2); p3.add(l5 = new Label("Scale:")); t4 = new TextField("30", 2 ); p3.add(t4); //p4に項目の追加 p4.setLayout(new BorderLayout()); p4.resize(300,100); p4.add("North",p2); p4.add("South",p3); Dimension s = new Dimension(300, 210); //nis zCanvas = new ZbufCanvas(); Bezier = new BezierApplet3();//jie zCanvas.setSize(s); zCanvas.setViewpoint(500,20,30); //nis zCanvas.setLightSource(30,60); Image buff=createImage(s.width, s.height); Graphics g1 = buff.getGraphics(); zCanvas.setImageBuffer(buff, g1); add("North", p1); add("Center",zCanvas); add("South", p4); resize(appsize); datafile = "rei61.pol"; datafile = "Ncharc.pol"; double ltheta = 30; double lphi = 60; scale =30; String str; if (( str = getParameter("scene")) != null) { datafile = getParameter(str); datafile = str; System.out.println("DataFile:"+datafile); } if ((str = getParameter("ltheta"))!= null) { ltheta = Double.valueOf(str).doubleValue(); } if ((str = getParameter("lphi")) != null) { lphi = Double.valueOf(str).doubleValue(); } if ((str = getParameter("Bez")) != null) { bezdat = (int)Double.valueOf(str).doubleValue(); } zCanvas.setLightSource(ltheta,lphi); t4.setText(""+scale); if(bezdat==0) polygon_read(); else Bez_read(bezdat); } public void paint(Graphics g) { } /** * 選択されたデータを読む */ public boolean action(Event evt, Object obj) { if (evt.target == b1) { //redraw double theta = Integer.parseInt(t1.getText()); double phi = Integer.parseInt(t2.getText()); double R = Integer.parseInt(t3.getText()); double scaleTMP = Integer.parseInt(t4.getText()); if((int)scale != (int)scaleTMP) { scale = scaleTMP; if(bezdat==0) polygon_read(); else Bez_read(bezdat); } zCanvas.setViewpoint(R,theta,phi); zCanvas.repaint(); return true; } else if(evt.target instanceof Checkbox) { Checkbox chk = (Checkbox)(evt.target); if(chk.getLabel().equals("Shading")) { zCanvas.setShadeMode(); zCanvas.repaint(); } else if(chk.getLabel().equals("Drawing")) { zCanvas.setLineMode(); zCanvas.repaint(); } } else if (evt.target == b2) { bezdat=0; switch(c.getSelectedIndex()) { case 0 : datafile = "Ncharc.pol"; scale = 30; t4.setText(""+scale); break; case 1 : datafile = "curve.dat"; t4.setText(""+scale); scale = 20; bezdat =9; break; case 2 : datafile = "Ncharc3.pol"; scale = 15; t4.setText(""+scale); break; case 3 : datafile = "Ncharctrue.pol"; scale = 30; t4.setText(""+scale); break; case 4 : datafile = "kyuu.dat"; scale = 70; t4.setText(""+scale); bezdat =6; break; case 5 : datafile = "kyuu2.dat"; scale = 60; t4.setText(""+scale); bezdat =6; break; case 6 : datafile = "tpot1.dat"; scale = 25; t4.setText(""+scale); bezdat =5; break; case 7: Bezier.BezierApplet4(); break; } if(bezdat==0) polygon_read(); else Bez_read(bezdat); zCanvas.repaint(); return true; }else if (evt.target == b3) { bez_read2(); zCanvas.repaint(); return true; } else return super.action(evt, obj); return false; } public void bez_read2(){ //jie int i, j, k; double x,y,z; int ndiv=4; int nsurf=Bezier.bcum*4;//1; int nface=0; int surf_deg[]=new int[Bezier.bcum*4]; Surface surfdata[]; surfdata=new Surface[Bezier.bcum*4]; surf_deg[0]=4; for(i=0;i<(Bezier.bcum*4);i++){ surfdata[i] = new Surface(); surf_deg[i]=4; for(j=0;j<4;j++){ for(k=0;k<4;k++){ x=Bezier.sdata[i][4*j+k][0]*100; y=Bezier.sdata[i][4*j+k][1]*100; z=Bezier.sdata[i][4*j+k][2]*100; surfdata[i].p[j][k] = new Point3(x,y,z); } } } nface = Bez2pol(ndiv,nsurf, surf_deg, surfdata); showStatus("No. of BezierPatches ="+ nsurf+ " faces="+nface); } public void polygon_read() { int nv, nf=0; try { InputStream is = new URL(getDocumentBase(), datafile).openStream(); DataInputStream dis = new DataInputStream(is); StringTokenizer st; double x, y, z; Vector vec; String comment; st = new StringTokenizer(dis.readLine()); int nobjects = Integer.parseInt(st.nextToken()); zCanvas.setNumObject(nobjects); comment = st.nextToken(); for(int k=0; k= 0) vec.addElement(new Integer(num)); } zCanvas.object[k].AddPlane(vec); } } is.close(); showStatus("ReadEnd; No. of polygons ="+ nf); } catch (IOException e) { System.err.println("Can't access datafile " + datafile); } } public void Bez_read(int ndiv) { int nsurf=0; int surf_deg[]; Surface surfdata[]; showStatus("Read Data-file Start! data_file="+datafile); int nface =0; try { InputStream is = new URL(getDocumentBase(), datafile).openStream(); DataInputStream dis = new DataInputStream(is); StringTokenizer st; double x, y, z; st = new StringTokenizer(dis.readLine()); nsurf = Integer.parseInt(st.nextToken()); showStatus("ReadStart; No. of BezierPatches ="+ nsurf); surfdata = new Surface[nsurf]; surf_deg = new int[nsurf]; dis.readLine(); for (int i = 0; i < nsurf; i++) { dis.readLine(); st = new StringTokenizer(dis.readLine()); st.nextToken(); surf_deg[i] = Integer.parseInt(st.nextToken()); surfdata[i] = new Surface(); for(int j = 0; j < surf_deg[i] ;j++){ for(int k = 0; k < surf_deg[i]; k++){ st = new StringTokenizer(dis.readLine()); x = Double.valueOf(st.nextToken()).doubleValue()*scale; y = Double.valueOf(st.nextToken()).doubleValue()*scale; z = Double.valueOf(st.nextToken()).doubleValue()*scale; surfdata[i].p[j][k] = new Point3(x,y,z); } } } // end nsurf is.close(); nface = Bez2pol(ndiv,nsurf, surf_deg, surfdata); } catch (IOException e) { System.err.println("Can't access datafile " + datafile); } showStatus("No. of BezierPatches ="+ nsurf+ " faces="+nface); } public int Bez2pol(int mdiv,int nsurf, int surf_deg[],Surface surfdata[]) { Point3 plt[][]; double u; Point3[] pnt1 = new Point3[11]; Point3[] pnt = new Point3[11]; Vector vec; int nv, nf ,k,l,m,ndiv,nface; int[] face = new int[5]; plt = new Point3[11][11]; zCanvas.setNumObject(nsurf); System.err.println("nsurf="+nsurf); nface =0; nf = 0; for(int i_surf=0;i_surf 0.2) vec.addElement(new Integer(face[m])); } zCanvas.object[i_surf].AddPlane(vec); nface++; } } } // end of i_surf System.err.println("No. of BezierPatches ="+ nsurf+ " faces="+nface); return nface; } /* ----------------------------------*/ public Point3 castljau(double u, int ndeg, Point3 cpnt[]){ double[] wx = new double[10]; double[] wy = new double[10]; double[] wz = new double[10]; for (int i=0; i <=ndeg; i++){ wx[i] = cpnt[i].x; wy[i] = cpnt[i].y; wz[i] = cpnt[i].z; } for (int m=1; m <= ndeg; m++) { for (int j=0; j <= ndeg - m; j++){ wx[j] += (wx[j+1]-wx[j])*u ; wy[j] += (wy[j+1]-wy[j])*u ; wz[j] += (wz[j+1]-wz[j])*u ; } } return new Point3(wx[0],wy[0],wz[0]); } } // end of class class ZbufCanvas extends Canvas implements Runnable{ Dimension appsize; Image gs; Graphics gr; Obj object[]; int nobjects; Point3 ptViewRef = new Point3(0, 0, 0); // view reference point double theta, phi, R, cos_theta, cos_phi, sin_theta, sin_phi; double ltheta, lphi, amb = 0.42; //nis Hashtable ht; Point prev = new Point(150,185); Polygon poly; int depth[]; EdgeTable et; Point3 light_vect = new Point3(); Zbuffer zbuf; //z-buffer //nis Point origin; int linedraw = 0; int drag = 0; public Thread kick = null;//double buffer public ZbufCanvas() {} /* public void paint(Graphics g) { computePlane(); render(); g.drawImage(gs, 0, 0, this); } */ public void paint(Graphics g) { update(g); } public void update(Graphics g) { computePlane(); render(); g.drawImage(gs, 0, 0, this); } public void setImageBuffer(Image b, Graphics g) { gs = b; gr = g; } public void setSize(Dimension s) { appsize = s; origin = new Point(appsize.width/2, appsize.height/2+5);//nis zbuf = new Zbuffer(appsize); zbuf.clearBuffer(); resize(appsize); } public void setNumObject(int n) { nobjects = n; object = new Obj[nobjects]; for(int i=0; i= 3.5) { //nis visible = true; } else { visible = false; } } } /** Z-Buffer Class **/ class Zbuffer { Dimension size; int buffer[]; double far; public Zbuffer(Dimension s) { size = s; far = 5000.; buffer = new int[size.width * size.height]; } public void clearBuffer() { for(int i=0; i iy && size.width > ix && iy > -1 && ix > -1) { int index = iy*size.width+ix; double zz=Integer.MAX_VALUE*(z/far); int iz = (int)(Integer.MAX_VALUE*(z/far)); if(iz < buffer[index]) { buffer[index] = iz; return true; } } return false; } } /** * Edge table for y-sort. */ class EdgeTable { public int xmin[], ymin[], ymax[],zmin[]; double invM[]; double gradZ[]; Zbuffer zbuf; public int nsize = 0; static final int MIN = 0; static final int MID = 1; static final int MAX = 2; EdgeTable(Polygon poly, int depth[], Zbuffer zb) { xmin = new int[poly.npoints-1]; ymin = new int[poly.npoints-1]; ymax = new int[poly.npoints-1]; zmin = new int[poly.npoints-1]; invM = new double[poly.npoints-1]; gradZ = new double[poly.npoints-1]; zbuf = zb; for (int i = 0; i < poly.npoints-1; i++) { if (poly.ypoints[i] < poly.ypoints[i+1]) { xmin[nsize] = poly.xpoints[i]; ymin[nsize] = poly.ypoints[i]; ymax[nsize] = poly.ypoints[i+1]; zmin[nsize] = depth[i]; } else { xmin[nsize] = poly.xpoints[i+1]; ymin[nsize] = poly.ypoints[i+1]; ymax[nsize] = poly.ypoints[i]; zmin[nsize] = depth[i+1]; } if (poly.ypoints[i] != poly.ypoints[i+1]) { if(Math.abs(poly.ypoints[i]-poly.ypoints[i+1])<0.1) { invM[nsize] = 0.; //nis } else { invM[nsize] = (double)(poly.xpoints[i]-poly.xpoints[i+1])/ (poly.ypoints[i]-poly.ypoints[i+1]); } if(Math.abs(poly.ypoints[i]-poly.ypoints[i+1])<0.1) { gradZ[nsize] = 0.; //nis } else {gradZ[nsize] = (double)(depth[i]-depth[i+1])/ (poly.ypoints[i]-poly.ypoints[i+1]); } nsize++; } } ySort(); } /** * Y-sort */ void ySort() { for (int i = 0; i < nsize; i++) { for (int j = 0; j < nsize-i-1; j++) { if (ymin[j] > ymin[j+1]) { swap(j, j+1); } } } } /** * Swaps table contents. */ void swap(int i, int j) { int temp; double tempd; temp = xmin[i]; xmin[i] = xmin[j]; xmin[j] = temp; temp = ymin[i]; ymin[i] = ymin[j]; ymin[j] = temp; temp = ymax[i]; ymax[i] = ymax[j]; ymax[j] = temp; temp = zmin[i]; zmin[i] = zmin[j]; zmin[j] = temp; tempd = invM[i]; invM[i] = invM[j]; invM[j] = tempd; tempd = gradZ[i]; gradZ[i] = gradZ[j]; gradZ[j] = tempd; } /** * Paint clipped polygon */ public void paint(Graphics g) { double xpoints[] = new double[nsize]; double zpoints[] = new double[nsize]; int vertex[] = new int[nsize]; double x[] = new double[nsize]; double z[] = new double[nsize]; for (int i = 0; i < nsize; i++) { x[i] = xmin[i]; z[i] = zmin[i]; } for (int scanline = ymin[0]; ; scanline++) { int npoint = 0; for (int i = 0; i < nsize; i++) { if (scanline > ymin[i] && scanline < ymax[i]) { if (insert(xpoints, zpoints, vertex, x[i], z[i], MID, npoint)) { npoint++; } x[i] += invM[i]; z[i] += gradZ[i]; } else if (scanline == ymin[i]) { if (insert(xpoints, zpoints, vertex, x[i], z[i], MIN, npoint)) { npoint++; } x[i] += invM[i]; z[i] += gradZ[i]; } else if (scanline == ymax[i]) { if (insert(xpoints, zpoints, vertex, x[i], z[i], MAX, npoint)) { npoint++; } x[i] += invM[i]; z[i] += gradZ[i]; } } if (npoint == 0) { break; } for (int i = 0; i < npoint; i += 2) { int ix1 = (int)xpoints[i]; int ix2 = (int)xpoints[i+1]; double dz = 0.; if((ix2-ix1)<1) { // System.err.println("ix1="+ix1+" ix2="+ix2); } else { dz = (zpoints[i+1]-zpoints[i])/(ix2-ix1);} double zz = zpoints[i]; for(int ix=ix1; ix= xmin) { for (int j = npoint-1; j >= i; j--) { xpoints[j+1] = xpoints[j]; zpoints[j+1] = zpoints[j]; vertex[j+1] = vertex[j]; } break; } i++; } xpoints[i] = xmin; zpoints[i] = zmin; vertex[i] = attr; return true; } } /** * 3D real point class */ class Point3 { public double x, y, z; Point3() { } Point3(double ox, double oy, double oz) { x = ox; y = oy; z = oz; } } class ATT { public RGB dif, amb, spc; public double power; public int shade,side,smooth; ATT() { dif = new RGB(); amb = new RGB(); spc = new RGB(); } } class RGB { public double r, g, b; RGB() { } RGB(double rr, double gg, double bb) { r=rr; g=gg; b=bb; } } class Surface { public Point3 p[][]; Surface(){ p = new Point3[4][4]; for (int i = 0; i < 4;i++){ for (int j =0; j< 4;j++){ p[i][j]=new Point3(0,0,0); } } } } class BezierApplet3 extends Frame{ Dimension d; BezierCurve bcurve; BezierSurface bsurface[]; Bezier_read Bezier_R; Graphics graph; Image offImage; boolean modeEdit; Choice changeMode; Choice changeMode2; Button con; double sdata[][][]; int bcum; BezierApplet3(){ super("Bezier"); // setBackground(new Color(75,86,97));//) darkGray); // setForeground(new Color(75,86,97));//Color.red); // setLayout(new BorderLayout(0,0)); changeMode = new Choice(); changeMode.addItem("Editing Mode"); changeMode.addItem("Browsing Mode"); changeMode2 = new Choice(); changeMode2.addItem("4"); changeMode2.addItem("5"); changeMode2.addItem("6"); changeMode2.addItem("7"); con = new Button("draw"); Bezier_R= new Bezier_read(); modeEdit = true; } public void BezierApplet4(){ System.out.println("Yes!!"); d = size(); d.width=500; d.height=550; show(); setBackground(new Color(112,128,144)); resize(d.width,d.height); changeMode.select(0); changeMode2.select(0); add(changeMode); changeMode.reshape(150,30,100,80); add(changeMode2); changeMode2.reshape(300,30,40,80); // add(con); // con.reshape(360,30,40,20); offImage = createImage(d.width, d.height); graph = offImage.getGraphics(); Getcontnum(3); } public void Getcontnum(int n){ bcurve = new BezierCurve(n); bsurface = new BezierSurface[4*bcurve.cnum]; for (int i=0; i=0){ bcurve.setControlPoint(event.x, event.y); repaint(); } break; } return true; } boolean browserEvent(Event event){ int i; if (event.target == con){ System.out.println("sss"); Bezier_R.bez_read2(); return true; } switch (event.id){ case Event.MOUSE_DOWN: double theta, delta, dx, dy; dx = event.x - d.width/2; dy = d.height/2 - event.y; if (dx==0){ if (dy>0){ theta = Math.PI/2; }else{ theta = -Math.PI/2; } }else{ theta = Math.atan(dy/dx); } delta = Math.PI/12; if (dx<0) delta = -delta; for (i=0; i=0){ switch(kind){ case 0: bx = x - (int)point[1][0]; by = y - (int)point[1][1]; point[0][0] = x; point[0][1] = y; bdist = Math.sqrt(bx*bx+by*by); point[2][0] = point[1][0] - bx*fdist/bdist; point[2][1] = point[1][1] - by*fdist/bdist; break; case 1: bx = (int)point[0][0]-(int)point[1][0]; by = (int)point[0][1]-(int)point[1][1]; fx = (int)point[2][0]-(int)point[1][0]; fy = (int)point[2][1]-(int)point[1][1]; point[1][0] = x; point[1][1] = y; point[0][0] = x+bx; point[0][1] = y+by; point[2][0] = x+fx; point[2][1] = y+fy; break; case 2: fx = x - (int)point[1][0]; fy = y - (int)point[1][1]; point[2][0] = x; point[2][1] = y; fdist = Math.sqrt(fx*fx+fy*fy); point[0][0] = point[1][0] - fx*bdist/fdist; point[0][1] = point[1][1] - fy*bdist/fdist; break; } } } public void draw(Graphics g){ g.setColor(Color.green); //Drawing Control Line g.drawLine((int)point[0][0], (int)point[0][1], (int)point[1][0], (int)point[1][1]); g.drawLine((int)point[1][0], (int)point[1][1], (int)point[2][0], (int)point[2][1]); // Drawing Control Point g.drawOval((int)point[0][0] - 3, (int)point[0][1] - 3, 6, 6); g.drawRect((int)point[1][0] - 3, (int)point[1][1] - 3, 6, 6); g.drawOval((int)point[2][0] - 3, (int)point[2][1] - 3, 6, 6); } public void drawSelect(Graphics g){ g.setColor(Color.green); //Drawing Control Line g.drawLine((int)point[0][0], (int)point[0][1], (int)point[1][0], (int)point[1][1]); g.drawLine((int)point[1][0], (int)point[1][1], (int)point[2][0], (int)point[2][1]); // Drawing Control Point if (kind==0||kind==1) g.fillOval((int)point[0][0] - 3, (int)point[0][1] - 3, 6, 6); else g.drawOval((int)point[0][0] - 3, (int)point[0][1] - 3, 6, 6); if (kind==1) g.fillRect((int)point[1][0] - 3, (int)point[1][1] - 3, 6, 6); else g.drawRect((int)point[1][0] - 3, (int)point[1][1] - 3, 6, 6); if (kind==1||kind==2) g.fillOval((int)point[2][0] - 3, (int)point[2][1] - 3, 6, 6); else g.drawOval((int)point[2][0] - 3, (int)point[2][1] - 3, 6, 6); } } class BezierSurface { int dnum; int point[][][]; double patch[][][]; double weight1[], weight2[], weight3[], weight4[]; public BezierSurface(double pp[][]){ int i, j, k; patch = new double[4][4][3]; for(i=0; i<4; i++){ for (j=0; j<4; j++){ for (k=0; k<3; k++){ patch[i][j][k] = pp[4*i+j][k]; } } } setDivideNum(8); } public void setDivideNum(int num){ dnum = num+1; weight1 = new double[dnum]; weight2 = new double[dnum]; weight3 = new double[dnum]; weight4 = new double[dnum]; point = new int[dnum][dnum][2]; calcWeight(); } void calcWeight(){ int i; for (i=0; i