00000000.htm
来自「水木清华BBS」· HTM 代码 · 共 510 行 · 第 1/2 页
HTM
510 行
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: VolVis (arthur), 信区: Java <BR>标 题: Java example(1) <BR>发信站: BBS 水木清华站 (Fri Dec 25 13:36:27 1998) WWW-POST <BR> <BR>Dear Everyone:
<BR>
<BR>I just have read a java program to draw a 3d face was written by Daeron
<BR>Meyer, The Geometry Center, University of Minnesota. I do think it is a good
<BR>program to illustrate the java appletview and the 3d Graphics although it
<BR>only draw a polygon without clipping and lingting. It inludes three class:
<BR>Viewer3D, Matrix3D and OOGL_OFF. The most important class is OOGL_OFF, I <BR>will
<BR>explain it and the other 2 class in the java program.The last part was one <BR>OFF
<BR>format file and one html file.I hope it will be helpful to you.
<BR>
<BR>
<BR>Yours VolVis
<BR>Information Department of Peking University
<BR>The following will give you a detailed explaination about the class OOGL_OFF
<BR>(1) findBB() is to calculate the bounding box of the object
<BR> why? the answer is to put all the vertices in a box, so the coordinate
<BR> transform can the (0,0,0) to be the object center.
<BR>(2) paint() is the most function in the class OOGL_OFF, for it using the
<BR> Painter's algorithm to paint the scenes. Do you know the Painter's
<BR> algorithm? The algorithm is to align the object in the reverse erder of
<BR> their distance from the eye. As common, the eye is placed in minus z <BR>axis,
<BR> so the sort the object according to object parameter depth. The the <BR>farther
<BR> object will be painted earlier, and the nearest object will be painted <BR>the
<BR> latest. Perhaps, the nearer object will hide the farther object. Let's <BR>see
<BR> the java program: At first, it will allocate the color for the face
<BR> gr[i] = new Color(face[i].cr, face[i].cg, face[i].cb) 0 <= i <= number <BR>of
<BR> faces. then quick sort the faces by the qs function whose algorithm is
<BR> the same asthe dividing method in data structure. At last paint the
<BR> faces by the function g.fillPolygon(vx, vy, face[i].nverts) and paint <BR>the
<BR> edges by the function g.drawLine(vx[v], vy[v], vx[v+1], vy[v+1])
<BR>(3) the readObject function is to read the faces from the OFF file. The <BR>first
<BR> line of OFF file is the tag OFF, the following is number of vertices ,
<BR> number of faces, and number of edges. Then the three dimensional data of
<BR> vertices is following them. The next thing is data of faces, including <BR>the
<BR> number of vertices in the face, the vertex index, and the color of face. <BR>i
<BR> In the OFF file, you can add any comment with the head #. Now, if you <BR>are
<BR> familiar with the java, you can read the OFF file either. But I have to
<BR> remind you that the class StreamTokenizer is a good way to do this work.
<BR>
<BR>/**
<BR> *
<BR> * Author: Daeron Meyer
<BR> * Copyright (c) 1995 by The Geometry Center, University of Minnesota
<BR> * Distributed under the terms of the GNU Library General Public License
<BR> * 12-14-95
<BR> *
<BR> */
<BR>
<BR>import java.applet.Applet;
<BR>import java.awt.Graphics;
<BR>import java.awt.Color;
<BR>import java.awt.Event;
<BR>import java.lang.*;
<BR>import java.io.StreamTokenizer;
<BR>import java.io.InputStream;
<BR>import java.io.IOException;
<BR>import java.net.URL;
<BR>
<BR>/**
<BR> * class Face: your basic storage class for polygonal face information.
<BR> */
<BR>
<BR>class Face {
<BR>
<BR> public int nverts; // number of vertices
<BR> public int index[]; // array of indices
<BR> public int cr, cg, cb; // face color in RGB
<BR> public int zdepth; // z depth of furthest vertex
<BR>
<BR> Face () {
<BR> nverts = 0;
<BR> index = null;
<BR> cr = 255; cg = 255; cb = 255;
<BR> }
<BR>
<BR> Face (int nv) {
<BR> nverts = nv;
<BR> index = new int[nv];
<BR> cr = 255; cg = 255; cb = 255;
<BR> }
<BR>
<BR> public void numVerts(int nv) {
<BR> nverts = nv;
<BR> index = new int[nv];
<BR> }
<BR>}
<BR>
<BR>/**
<BR> * class OOGL_OFF: a class for parsing, storing and rendering OFF 3D models
<BR> *
<BR> * For more information about OFF files and other OOGL (Object Oriented
<BR> * Graphics Library) file formats, check the following URL:
<BR> *
<BR> * <A HREF="http://www.geom.umn.edu/software/geomview/docs/oogltour.html
">http://www.geom.umn.edu/software/geomview/docs/oogltour.html
</A> <BR> */
<BR>
<BR>public class OOGL_OFF {
<BR>
<BR> Face face[]; // array of faces
<BR> boolean transformed, gothead;
<BR> Matrix3D mat; // applied 3D transformation
<BR> public float xmin, xmax, // bounding box parameters
<BR> ymin, ymax,
<BR> zmin, zmax;
<BR> float vert[]; // array of vertex coordinates
<BR> int nverts, nfaces, nedges, // # of vertices, faces, edges
<BR> vx[], vy[], // coords for rendering faces
<BR> tvert[], // transformed vertices
<BR> findex[]; // indices into face list
<BR> Color gr[]; // face colors
<BR> final int MAX_VERTS = 100; // assume each polygonal face
<BR> // has less than 100 vertices.
<BR>
<BR> OOGL_OFF () {
<BR> mat = new Matrix3D();
<BR> vx = new int[MAX_VERTS];
<BR> vy = new int[MAX_VERTS];
<BR> nverts = 0;
<BR> nedges = 0;
<BR> nfaces = 0;
<BR> vert = null;
<BR> gr = null;
<BR> mat.xrot(0); mat.yrot(0);
<BR> }
<BR>
<BR> OOGL_OFF (URL loc) { // read object from any URL
<BR>
<BR> this();
<BR> try {
<BR> readObject(loc.openStream());
<BR> } catch (IOException e) {
<BR> System.out.println(e.getMessage());
<BR> }
<BR>
<BR> }
<BR>
<BR> OOGL_OFF (InputStream is) { // read object from a stream
<BR>
<BR> this();
<BR> try {
<BR> readObject(is);
<BR> } catch (IOException e) {
<BR> System.out.println(e.getMessage());
<BR> }
<BR>
<BR> }
<BR>
<BR>
<BR>/* This method parses an OFF file. */
<BR>
<BR> void readObject(InputStream is) throws IOException {
<BR>
<BR> StreamTokenizer stream = new StreamTokenizer (is);
<BR>
<BR> stream.eolIsSignificant(true);
<BR> stream.commentChar('#');
<BR> gothead = false;
<BR>
<BR> scanhead: // read the header
<BR>
<BR> while (!gothead) {
<BR>
<BR> switch (stream.nextToken()) {
<BR>
<BR> default:
<BR> break scanhead;
<BR>
<BR> case StreamTokenizer.TT_EOL:
<BR> break;
<BR>
<BR> case StreamTokenizer.TT_WORD:
<BR>
<BR> if ("OFF".equals(stream.sval)) {
<BR>
<BR> System.out.println(stream.sval);
<BR>
<BR> nverts = 0; nfaces = 0; nedges = 0;
<BR> while (stream.nextToken() == StreamTokenizer.TT_EOL) {};
<BR>
<BR> if (stream.ttype == StreamTokenizer.TT_NUMBER) {
<BR>
<BR> nverts = (int)stream.nval;
<BR> if (stream.nextToken() == StreamTokenizer.TT_NUMBER) {
<BR>
<BR> nfaces = (int)stream.nval;
<BR> if (stream.nextToken() == StreamTokenizer.TT_NUMBER) {
<BR>
<BR> nedges = (int)stream.nval;
<BR> gothead = true;
<BR>
<BR> } else throw new IOException("Can't read OFF file");
<BR>
<BR> } else throw new IOException("Can't read OFF file");
<BR>
<BR> } else throw new IOException("Can't read OFF file");
<BR>
<BR> }
<BR> break;
<BR>
<BR> case StreamTokenizer.TT_NUMBER:
<BR> break;
<BR>
<BR> }
<BR>
<BR> }
<BR>
<BR> vert = new float[nverts * 3];
<BR> face = new Face[nfaces]; findex = new int[nfaces];
<BR>
<BR> for (int i = 0; i < nfaces; i++) { findex[i] = i; }
<BR>
<BR> int num = 0;
<BR> int coordnum = 0;
<BR>
<BR> scanverts: // read the vertices
<BR>
<BR> while (num < nverts) {
<BR>
<BR> switch (stream.nextToken()) {
<BR>
<BR> default:
<BR> break;
<BR>
<BR> case StreamTokenizer.TT_EOL:
<BR> if (coordnum > 2) {
<BR> coordnum = 0; num++;
<BR> }
<BR> break;
<BR>
<BR>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?