⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 用java编程画3d的一张动画人物的脸.txt

📁 用JAVA编程画3D的一张动画人物的脸
💻 TXT
字号:
import java.applet.Applet;  
import java.awt.Graphics;  
import java.awt.Color;  
import java.awt.Event;  
import java.lang.*;  
import java.io.StreamTokenizer;  
import java.io.InputStream;  
import java.io.IOException;  
import java.net.URL;  
 
/**  
 *  class Face: your basic storage class for polygonal face information.  
 */  
 
class Face {  
 
  public int nverts; // number of vertices  
  public int index[]; // array of indices  
  public int cr, cg, cb; // face color in RGB  
  public int zdepth; // z depth of furthest vertex  
 
  Face () {  
    nverts = 0;  
    index = null;  
    cr = 255; cg = 255; cb = 255;  
  }  
 
  Face (int nv) {  
    nverts = nv;  
    index = new int[nv];  
    cr = 255; cg = 255; cb = 255;  
  }  
 
  public void numVerts(int nv) {  
    nverts = nv;  
    index = new int[nv];  
  }  
}  
 
/**  
 *  class OOGL_OFF: a class for parsing, storing and rendering OFF 3D models  
 *  
 *  For more information about OFF files and other OOGL (Object Oriented  
 *  Graphics Library) file formats, check the following URL:  
 *  
 *  http://www.geom.umn.edu/software/geomview/docs/oogltour.html  
 */  
 
public class OOGL_OFF {  
 
  Face face[]; // array of faces  
  boolean transformed, gothead;  
  Matrix3D mat; // applied 3D transformation  
  public float xmin, xmax, // bounding box parameters  
ymin, ymax,  
zmin, zmax;  
  float vert[]; // array of vertex coordinates  
  int nverts, nfaces, nedges, // # of vertices, faces, edges  
vx[], vy[], // coords for rendering faces  
tvert[], // transformed vertices  
findex[]; // indices into face list  
  Color gr[]; // face colors  
  final int MAX_VERTS = 100; // assume each polygonal face  
// has less than 100 vertices.  
    
  OOGL_OFF () {  
    mat = new Matrix3D();  
    vx = new int[MAX_VERTS];  
    vy = new int[MAX_VERTS];  
    nverts = 0;  
    nedges = 0;  
    nfaces = 0;  
    vert = null;  
    gr = null;  
    mat.xrot(0); mat.yrot(0);  
  }  
 
  OOGL_OFF (URL loc) { // read object from any URL  
 
    this();  
    try {  
      readObject(loc.openStream());  
    } catch (IOException e) {  
      System.out.println(e.getMessage());  
    }  
 
  }  
    
  OOGL_OFF (InputStream is) { // read object from a stream  
 
    this();  
    try {  
      readObject(is);  
    } catch (IOException e) {  
      System.out.println(e.getMessage());  
    }  
 
  }  
 
 
/* This method parses an OFF file. */  
 
  void readObject(InputStream is) throws IOException {  
 
    StreamTokenizer stream = new StreamTokenizer (is);  
 
    stream.eolIsSignificant(true);  
    stream.commentChar('#');  
    gothead = false;  
 
  scanhead: // read the header  
 
    while (!gothead) {  
 
      switch (stream.nextToken()) {  
 
      default:  
break scanhead;  
 
      case StreamTokenizer.TT_EOL:  
break;  
 
      case StreamTokenizer.TT_WORD:  
 
if ("OFF".equals(stream.sval)) {  
            
          System.out.println(stream.sval);  
 
  nverts = 0; nfaces = 0; nedges = 0;  
  while (stream.nextToken() == StreamTokenizer.TT_EOL) {};  
 
  if (stream.ttype == StreamTokenizer.TT_NUMBER) {  
 
    nverts = (int)stream.nval;  
    if (stream.nextToken() == StreamTokenizer.TT_NUMBER) {  
 
      nfaces = (int)stream.nval;  
      if (stream.nextToken() == StreamTokenizer.TT_NUMBER) {  
 
nedges = (int)stream.nval;  
gothead = true;  
 
      } else throw new IOException("Can't read OFF file");  
 
    } else throw new IOException("Can't read OFF file");  
 
  } else throw new IOException("Can't read OFF file");  
 
}  
break;  
 
      case StreamTokenizer.TT_NUMBER:  
break;  
 
      }  
 
    }  
 
    vert = new float[nverts * 3];  
    face = new Face[nfaces]; findex = new int[nfaces];  
 
    for (int i = 0; i < nfaces; i++) { findex[i] = i; }  
 
    int num = 0;   
    int coordnum = 0;  
 
  scanverts: // read the vertices  
 
    while (num < nverts) {  
 
      switch (stream.nextToken()) {  
 
        default:  
  break;  
 
case StreamTokenizer.TT_EOL:  
  if (coordnum > 2) {  
    coordnum = 0; num++;  
  }  
  break;  
 
case StreamTokenizer.TT_NUMBER:  
  if (coordnum < 3) {  
    vert[num*3 + coordnum] = (float)stream.nval;  
    coordnum++;  
  }  
 
      }  
 
    }  
 
    num = 0; coordnum = 0;  
    boolean gotnum = false;  
 
  scanfaces: // read the faces  
 
    while (num < nfaces) {  
 
      switch (stream.nextToken()) {  
 
        default:  
  break;  
 
case StreamTokenizer.TT_EOL:  
  if (gotnum) { num++; }  
  gotnum = false;  
  break;  
 
case StreamTokenizer.TT_NUMBER:  
  if (!gotnum) {  
 
    face[num] = new Face();  
    face[num].numVerts((int)stream.nval);  
    gotnum = true; coordnum = 0;  
 
  } else if (coordnum < face[num].nverts) {  
 
    face[num].index[coordnum] = 3 * (int)stream.nval;  
    coordnum++;  
 
  } else {  
 
    face[num].cr = 255; face[num].cg = 255; face[num].cb = 255;  
    float val = (float)stream.nval;  
 
    if (val <= 1) { val *= 255; }  
 
    face[num].cr = (int)val;  
 
    if (stream.nextToken() != StreamTokenizer.TT_EOL) {  
 
      val = (float)stream.nval;  
      if (val <= 1) { val *= 255; }  
      face[num].cg = (int)val;  
 
      if (stream.nextToken() != StreamTokenizer.TT_EOL) {  
 
val = (float)stream.nval;  
        if (val <= 1) { val *= 255; }  
face[num].cb = (int)val;  
 
      } else {  
 
face[num].cr = 255; face[num].cg = 255; face[num].cb = 255;  
num++; gotnum = false;  
 
      }  
 
    } else {  
 
face[num].cr = 255; face[num].cg = 255; face[num].cb = 255;  
num++; gotnum = false;  
 
      }  
  }  
 
  break;  
 
      }  
 
    }  
       
 
  }  
 
 
/* transform all points in model */  
 
  void transform() {  
 
    if (transformed || nverts <= 0)  
      return;  
 
    if (tvert == null)  
      tvert = new int[nverts*3];  
 
    mat.transform(vert, tvert, nverts);  
    transformed = true;  
  }  
 
 
/**  
 *  The quick sort algorithm in this method is used for sorting faces  
 *  from back to front by z depth values.  
 */  
 
  void qs(int left, int right) {  
 
    int i, j, x, y;  
 
    i = left; j = right;  
    x = face[findex[(left+right)/2]].zdepth;  
 
    do {  
 
      while (face[findex[i]].zdepth > x && i < right) i++;  
      while (x > face[findex[j]].zdepth && j > left) j--;  
 
      if (i <= j) {  
y = findex[i];  
findex[i] = findex[j];  
findex[j] = y;  
i++; j--;  
      }  
 
    } while (i <= j);  
 
    if (left < j) qs(left, j);  
    if (i < right) qs(i, right);  
 
  }  
 
 
/* Paint myself to the graphics context. */  
 
  void paint(Graphics g) {  
 
    if (vert == null || nverts <= 0)  
      return;  
 
    transform();  
 
    if (gr == null) { // allocate colors if  
// they haven't been  
      gr = new Color[nfaces]; // allocated already  
 
      for (int i = 0; i < nfaces; i++) {  
 
gr[i] = new Color(face[i].cr, face[i].cg, face[i].cb);  
 
      }  
 
    }  
 
/**  
 *  Calculate the average z depth of faces and use this to sort them.  
 *  This is called the "Painter's algorithm" and although it works in  
 *  some case, does *not* always provide a correct ordering. Sometimes  
 *  a correct ordering is impossible, especially in the case of mutually  
 *  overlapping polygons.  
 */  
 
    for (int i = 0; i < nfaces; i++) {  
 
      face[i].zdepth = 0;  
 
      for (int c = 0; c < face[i].nverts; c++) {  
 
if (face[i].zdepth < tvert[face[i].index[c]+2])  
  face[i].zdepth = tvert[face[i].index[c]+2];  
      }  
 
    }  
 
    qs(0, nfaces-1); // quick sort the faces  
 
    for (int f = 0; f < nfaces; f++) {  
 
      int i = findex[f];  
      int v = 0;  
 
      for (int c = 0; c < face[i].nverts; c++) {  
vx[c] = tvert[face[i].index[c]];  
vy[c] = tvert[face[i].index[c]+1];  
      }  
 
      g.setColor(gr[i]);  
      g.fillPolygon(vx, vy, face[i].nverts); // draw each face  
 
      g.setColor(Color.black);  
 
      for (v = 0; v < (face[i].nverts-1); v++) {  
g.drawLine(vx[v], vy[v], vx[v+1], vy[v+1]); // draw the face edges  
      }  
 
      g.drawLine(vx[v], vy[v], vx[0], vy[0]);  
 
    }  
 
  }  
 
/* calculate the bounding box of our object: */  
 
  void findBB() {  
    if (nverts <= 0)  
      return;  
 
    float v[] = vert;  
    float xmin = v[0], xmax = xmin;  
    float ymin = v[1], ymax = ymin;  
    float zmin = v[2], zmax = zmin;  
 
    for (int i = nverts * 3; (i -= 3) > 0;) {  
 
      float x = v[i];  
      if (x < xmin)  
xmin = x;  
      if (x > xmax)  
xmax = x;  
      float y = v[i + 1];  
      if (y < ymin)  
ymin = y;  
      if (y > ymax)  
ymax = y;  
      float z = v[i + 2];  
      if (z < zmin)  
zmin = z;  
      if (z > zmax)  
zmax = z;  
 
    }  
 
    this.xmax = xmax;  
    this.xmin = xmin;  
    this.ymax = ymax;  
    this.ymin = ymin;  
    this.zmax = zmax;  
    this.zmin = zmin;  
 
  }  
 
}  
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -