FileDocCategorySizeDatePackage
XYZChemModel.javaAPI DocExample5216Sat Apr 23 22:35:42 BST 2005magicbeans.sunw.demo.molecule

XYZChemModel

public class XYZChemModel extends Object
The representation of a Chemical .xyz model

Fields Summary
float[]
vert
Atom[]
atoms
int[]
tvert
int[]
ZsortMap
int
nvert
int
maxvert
static Map
atomTable
static Atom
defaultAtom
boolean
transformed
Matrix3D
mat
float
xmin
float
xmax
float
ymin
float
ymax
float
zmin
float
zmax
Constructors Summary
XYZChemModel()

	mat = new Matrix3D();
	mat.xrot(20);
	mat.yrot(30);
    
XYZChemModel(InputStream is)
Create a Chemical model by parsing an input stream

	this();
        try {
	    StreamTokenizer st = new StreamTokenizer(
			new BufferedReader(new InputStreamReader(is)));
	    st.eolIsSignificant(true);
	    st.commentChar('#");
	    int slot = 0;
scan:
	    while (true) {
	        switch (st.nextToken()) {
	          case StreamTokenizer.TT_EOF:
		    break scan;
	          default:
		    break;
	          case StreamTokenizer.TT_WORD:
		    String name = st.sval;
		    double x = 0, y = 0, z = 0;
		    if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
		        x = st.nval;
		        if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
			    y = st.nval;
			    if (st.nextToken() == StreamTokenizer.TT_NUMBER)
			        z = st.nval;
		        }
		    }
		    addVert(name, (float) x, (float) y, (float) z);
		    while (st.ttype != StreamTokenizer.TT_EOL &&
			    st.ttype != StreamTokenizer.TT_EOF)
		        st.nextToken();
	        }
	    }
	    is.close();
	    if (st.ttype != StreamTokenizer.TT_EOF)
	        throw new Error(st.toString());
        } catch (Exception ex) {
    	    throw new Error("Input error: " + ex);
	}
    
Methods Summary
intaddVert(java.lang.String name, float x, float y, float z)
Add a vertex to this model

	int i = nvert;
	if (i >= maxvert)
	    if (vert == null) {
		maxvert = 100;
		vert = new float[maxvert * 3];
		atoms = new Atom[maxvert];
	    } else {
		maxvert *= 2;
		float nv[] = new float[maxvert * 3];
		System.arraycopy(vert, 0, nv, 0, vert.length);
		vert = nv;
		Atom na[] = new Atom[maxvert];
		System.arraycopy(atoms, 0, na, 0, atoms.length);
		atoms = na;
	    }
	Atom a = (Atom) atomTable.get(name.toLowerCase());
	if (a == null) a = defaultAtom;
	atoms[i] = a;
	i *= 3;
	vert[i] = x;
	vert[i + 1] = y;
	vert[i + 2] = z;
	return nvert++;
    
voidfindBB()
Find the bounding box of this model

	if (nvert <= 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 = nvert * 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;
    
synchronized voidpaint(java.awt.Graphics g)
Paint this model to a graphics context. It uses the matrix associated with this model to map from model space to screen space. The next version of the browser should have double buffering, which will make this *much* nicer

	if (vert == null || nvert <= 0)
	    return;
	transform();
	int v[] = tvert;
	int zs[] = ZsortMap;
	if (zs == null) {
	    ZsortMap = zs = new int[nvert];
	    for (int i = nvert; --i >= 0;)
		zs[i] = i * 3;
	}

	/*
	 * I use a bubble sort since from one iteration to the next, the sort
	 * order is pretty stable, so I just use what I had last time as a
	 * "guess" of the sorted order.  With luck, this reduces O(N log N)
	 * to O(N)
	 */

	for (int i = nvert - 1; --i >= 0;) {
	    boolean flipped = false;
	    for (int j = 0; j <= i; j++) {
		int a = zs[j];
		int b = zs[j + 1];
		if (v[a + 2] > v[b + 2]) {
		    zs[j + 1] = a;
		    zs[j] = b;
		    flipped = true;
		}
	    }
	    if (!flipped)
		break;
	}

	int lg = 0;
	int lim = nvert;
	Atom ls[] = atoms;
	if (lim <= 0 || nvert <= 0) {
	    return;
	}
	for (int i = 0; i < lim; i++) {
	    int j = zs[i];
	    int radius = v[j + 2];
	    if (radius < 0) {
		radius = 0;
	    } else if (radius > 15) {
		radius = 15;
	    }
	    atoms[j/3].paint(g, v[j], v[j + 1], radius);
	}
    
voidtransform()
Transform all the points in this model

	if (transformed || nvert <= 0)
	    return;
	if (tvert == null || tvert.length < nvert * 3)
	    tvert = new int[nvert * 3];
	mat.transform(vert, tvert, nvert);
	transformed = true;