home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 July / Chip_1998-07_cd.bin / zkuste / JBuilder / BDK / Win / bdk_sep97.exe / _SETUP.1 / XYZChemModel.java < prev    next >
Encoding:
Java Source  |  1997-09-10  |  5.0 KB  |  216 lines

  1. /*
  2.  * A set of classes to parse, represent and display Chemical compounds in
  3.  * .xyz format (see http://chem.leeds.ac.uk/Project/MIME.html)
  4.  */
  5.  
  6. package sunw.demo.molecule;
  7.  
  8. import java.io.*;
  9. import java.util.Hashtable;
  10.  
  11.  
  12. /** The representation of a Chemical .xyz model */
  13. class XYZChemModel {
  14.     float vert[];
  15.     Atom atoms[];
  16.     int tvert[];
  17.     int ZsortMap[];
  18.     int nvert, maxvert;
  19.  
  20.     static Hashtable atomTable = new Hashtable();
  21.     static Atom defaultAtom;
  22.     static {
  23.     atomTable.put("c", new Atom(0, 0, 0));
  24.     atomTable.put("h", new Atom(210, 210, 210));
  25.     atomTable.put("n", new Atom(0, 0, 255));
  26.     atomTable.put("o", new Atom(255, 0, 0));
  27.     atomTable.put("p", new Atom(255, 0, 255));
  28.     atomTable.put("s", new Atom(255, 255, 0));
  29.     atomTable.put("hn", new Atom(150, 255, 150)); /* !!*/
  30.     defaultAtom = new Atom(255, 100, 200);
  31.     }
  32.  
  33.     boolean transformed;
  34.     Matrix3D mat;
  35.  
  36.     float xmin, xmax, ymin, ymax, zmin, zmax;
  37.  
  38.  
  39.     XYZChemModel () {
  40.     mat = new Matrix3D();
  41.     mat.xrot(20);
  42.     mat.yrot(30);
  43.     }
  44.  
  45.  
  46.     /** Create a Chemical model by parsing an input stream */
  47.     XYZChemModel (InputStream is) {
  48.     this();
  49.         try {
  50.         StreamTokenizer st = new StreamTokenizer(
  51.             new BufferedReader(new InputStreamReader(is)));
  52.         st.eolIsSignificant(true);
  53.         st.commentChar('#');
  54.         int slot = 0;
  55. scan:
  56.         while (true) {
  57.             switch (st.nextToken()) {
  58.               case StreamTokenizer.TT_EOF:
  59.             break scan;
  60.               default:
  61.             break;
  62.               case StreamTokenizer.TT_WORD:
  63.             String name = st.sval;
  64.             double x = 0, y = 0, z = 0;
  65.             if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
  66.                 x = st.nval;
  67.                 if (st.nextToken() == StreamTokenizer.TT_NUMBER) {
  68.                 y = st.nval;
  69.                 if (st.nextToken() == StreamTokenizer.TT_NUMBER)
  70.                     z = st.nval;
  71.                 }
  72.             }
  73.             addVert(name, (float) x, (float) y, (float) z);
  74.             while (st.ttype != StreamTokenizer.TT_EOL &&
  75.                 st.ttype != StreamTokenizer.TT_EOF)
  76.                 st.nextToken();
  77.             }
  78.         }
  79.         is.close();
  80.         if (st.ttype != StreamTokenizer.TT_EOF)
  81.             throw new Error(st.toString());
  82.         } catch (Exception ex) {
  83.             throw new Error("Input error: " + ex);
  84.     }
  85.     }
  86.  
  87.     /** Add a vertex to this model */
  88.     int addVert(String name, float x, float y, float z) {
  89.     int i = nvert;
  90.     if (i >= maxvert)
  91.         if (vert == null) {
  92.         maxvert = 100;
  93.         vert = new float[maxvert * 3];
  94.         atoms = new Atom[maxvert];
  95.         } else {
  96.         maxvert *= 2;
  97.         float nv[] = new float[maxvert * 3];
  98.         System.arraycopy(vert, 0, nv, 0, vert.length);
  99.         vert = nv;
  100.         Atom na[] = new Atom[maxvert];
  101.         System.arraycopy(atoms, 0, na, 0, atoms.length);
  102.         atoms = na;
  103.         }
  104.     Atom a = (Atom) atomTable.get(name.toLowerCase());
  105.     if (a == null) a = defaultAtom;
  106.     atoms[i] = a;
  107.     i *= 3;
  108.     vert[i] = x;
  109.     vert[i + 1] = y;
  110.     vert[i + 2] = z;
  111.     return nvert++;
  112.     }
  113.  
  114.     /** Transform all the points in this model */
  115.     void transform() {
  116.     if (transformed || nvert <= 0)
  117.         return;
  118.     if (tvert == null || tvert.length < nvert * 3)
  119.         tvert = new int[nvert * 3];
  120.     mat.transform(vert, tvert, nvert);
  121.     transformed = true;
  122.     }
  123.  
  124.  
  125.     /**
  126.      * Paint this model to a graphics context.  It uses the matrix associated
  127.      * with this model to map from model space to screen space.
  128.      * The next version of the browser should have double buffering,
  129.      * which will make this *much* nicer 
  130.      */
  131.     synchronized void paint(java.awt.Graphics g) {
  132.     if (vert == null || nvert <= 0)
  133.         return;
  134.     transform();
  135.     int v[] = tvert;
  136.     int zs[] = ZsortMap;
  137.     if (zs == null) {
  138.         ZsortMap = zs = new int[nvert];
  139.         for (int i = nvert; --i >= 0;)
  140.         zs[i] = i * 3;
  141.     }
  142.  
  143.     /*
  144.      * I use a bubble sort since from one iteration to the next, the sort
  145.      * order is pretty stable, so I just use what I had last time as a
  146.      * "guess" of the sorted order.  With luck, this reduces O(N log N)
  147.      * to O(N)
  148.      */
  149.  
  150.     for (int i = nvert - 1; --i >= 0;) {
  151.         boolean flipped = false;
  152.         for (int j = 0; j <= i; j++) {
  153.         int a = zs[j];
  154.         int b = zs[j + 1];
  155.         if (v[a + 2] > v[b + 2]) {
  156.             zs[j + 1] = a;
  157.             zs[j] = b;
  158.             flipped = true;
  159.         }
  160.         }
  161.         if (!flipped)
  162.         break;
  163.     }
  164.  
  165.     int lg = 0;
  166.     int lim = nvert;
  167.     Atom ls[] = atoms;
  168.     if (lim <= 0 || nvert <= 0) {
  169.         return;
  170.     }
  171.     for (int i = 0; i < lim; i++) {
  172.         int j = zs[i];
  173.         int radius = v[j + 2];
  174.         if (radius < 0) {
  175.         radius = 0;
  176.         } else if (radius > 15) {
  177.         radius = 15;
  178.         }
  179.         atoms[j/3].paint(g, v[j], v[j + 1], radius);
  180.     }
  181.     }
  182.  
  183.     /** Find the bounding box of this model */
  184.     void findBB() {
  185.     if (nvert <= 0)
  186.         return;
  187.     float v[] = vert;
  188.     float xmin = v[0], xmax = xmin;
  189.     float ymin = v[1], ymax = ymin;
  190.     float zmin = v[2], zmax = zmin;
  191.     for (int i = nvert * 3; (i -= 3) > 0;) {
  192.         float x = v[i];
  193.         if (x < xmin)
  194.         xmin = x;
  195.         if (x > xmax)
  196.         xmax = x;
  197.         float y = v[i + 1];
  198.         if (y < ymin)
  199.         ymin = y;
  200.         if (y > ymax)
  201.         ymax = y;
  202.         float z = v[i + 2];
  203.         if (z < zmin)
  204.         zmin = z;
  205.         if (z > zmax)
  206.         zmax = z;
  207.     }
  208.     this.xmax = xmax;
  209.     this.xmin = xmin;
  210.     this.ymax = ymax;
  211.     this.ymin = ymin;
  212.     this.zmax = zmax;
  213.     this.zmin = zmin;
  214.     }
  215. }
  216.