/** * group.java - group of atoms and terms * Copyright (c) 1997 Will Ware, all rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * or its derived works must display the following acknowledgement: * This product includes software developed by Will Ware. * * This software is provided "as is" and any express or implied warranties, * including, but not limited to, the implied warranties of merchantability * or fitness for any particular purpose are disclaimed. In no event shall * Will Ware be liable for any direct, indirect, incidental, special, * exemplary, or consequential damages (including, but not limited to, * procurement of substitute goods or services; loss of use, data, or * profits; or business interruption) however caused and on any theory of * liability, whether in contract, strict liability, or tort (including * negligence or otherwise) arising in any way out of the use of this * software, even if advised of the possibility of such damage. */ import java.awt.*; import java.lang.Math; import java.util.Vector; import atom; import term; import view; import dlentry; import dl_atom; import dl_bond; import dlforce; public class group { public static final String rcsid = "$Id: group.java,v 1.39 1997/10/17 14:49:29 wware Exp $"; public Vector atomList; public Vector termList; private boolean needToEnumerateTerms; private boolean showForces = false; private Vector drawingList; public Panel mypanel; public view v; public double forceMultiplier = 100.0; public group () { v = new view (); empty (); } public group (Panel p) { mypanel = p; v = new view (); empty (); } public void updateViewSize () { Rectangle r = mypanel.bounds(); v.updateSize (r.width, r.height); } public void empty () { needToEnumerateTerms = true; atomList = new Vector (); termList = new Vector (); } public void setShowForces (boolean sf) { showForces = sf; } public atom selectedAtom (double[] scrPos, boolean picky) { int i; atom a, amin; double sqDist, minSqDist = 0; amin = null; for (i = 0; i < atomList.size (); i++) { a = (atom) atomList.elementAt (i); double[] atomPos = v.xyzToScreen (a.x); double dx = atomPos[0] - scrPos[0]; double dy = atomPos[1] - scrPos[1]; sqDist = dx * dx + dy * dy; if (sqDist < minSqDist || i == 0) { minSqDist = sqDist; amin = a; } } // if we're picky, we need to be right on top of the atom if (!picky || minSqDist < 0.05 * v.zoomFactor * v.zoomFactor) return amin; else return null; } public void addAtom (atom a) { needToEnumerateTerms = true; atomList.addElement (a); } public void addAtom (atom a, double[] scrPos) { needToEnumerateTerms = true; a.x = v.screenToXyz (scrPos); atomList.addElement (a); } public void addAtom (atom a, double x0, double x1, double x2) { needToEnumerateTerms = true; a.x[0] = x0; a.x[1] = x1; a.x[2] = x2; atomList.addElement (a); } public void deleteAtom (atom a) { int i; if (atomList.size () == 0) return; needToEnumerateTerms = true; // remove all bonds connected to the atom for (i = 0; i < atomList.size (); i++) { atom a2 = (atom) atomList.elementAt (i); if (a2.bonds.contains (a)) a2.bonds.removeElement (a); } // remove the atom atomList.removeElement (a); } public void addBond (atom a1, atom a2) { if (a1 == null || a2 == null) return; if (a1.bonds.contains (a2)) return; needToEnumerateTerms = true; a1.bonds.addElement (a2); a2.bonds.addElement (a1); a1.rehybridize (); a2.rehybridize (); } public void addBond (int a1, int a2) { atom at1 = (atom) atomList.elementAt (a1), at2 = (atom) atomList.elementAt (a2); addBond (at1, at2); } public void deleteBond (atom a1, atom a2) { if (!a1.bonds.contains (a2)) return; needToEnumerateTerms = true; a1.bonds.removeElement (a2); a2.bonds.removeElement (a1); a1.rehybridize (); a2.rehybridize (); } public void centerAtoms () { int i, j; atom a; double[] x = { 0, 0, 0 }; for (i = 0; i < atomList.size (); i++) { a = (atom) atomList.elementAt (i); for (j = 0; j < 3; j++) x[j] += a.x[j]; } for (j = 0; j < 3; j++) x[j] /= atomList.size (); for (i = 0; i < atomList.size (); i++) { a = (atom) atomList.elementAt (i); for (j = 0; j < 3; j++) a.x[j] -= x[j]; } } public void drawLineToAtom (atom a, double x, double y) { dl_atom dummy = new dl_atom (a, v); dummy.drawLineToAtom (a, x, y, mypanel.getGraphics ()); } public void bubblePaint () { int i; Vector dlist = new Vector (); dl_atom dla = null; for (i = 0; i < atomList.size (); i++) { dla = new dl_atom ((atom) atomList.elementAt (i), v); dlist.addElement (dla); } if (dla != null) dla.quickpaint (dlist, mypanel.getGraphics ()); } public void wireframePaint () { int i, j; Vector dlist = new Vector (); dl_atom dla = null; dl_bond dlb = null; for (i = 0; i < atomList.size (); i++) { atom a = (atom) atomList.elementAt (i); if (a.sigmaBonds () == 0) { dla = new dl_atom (a, v); dlist.addElement (dla); } } for (i = 0; i < atomList.size (); i++) { atom a1 = (atom) atomList.elementAt (i); for (j = 0; j < a1.bonds.size (); j++) { atom a2 = (atom) a1.bonds.elementAt (j); if (atomList.indexOf (a2) > i) { dlb = new dl_bond (a1, a2, v); dlist.addElement (dlb); } } } if (dla != null) dla.quickpaint (dlist, mypanel.getGraphics ()); else if (dlb != null) dlb.quickpaint (dlist, mypanel.getGraphics ()); } public void paint () { int i, j; dl_atom dla = null; dl_bond dlb = null; Vector dlist = new Vector (); if (showForces) computeForces (); for (i = 0; i < atomList.size (); i++) { dla = new dl_atom ((atom) atomList.elementAt(i), v); dlist.addElement (dla); } for (i = 0; i < atomList.size (); i++) { atom a1 = (atom) atomList.elementAt (i); for (j = i + 1; j < atomList.size (); j++) { atom a2 = (atom) atomList.elementAt (j); if (a1.bonds.contains (a2)) { dlb = new dl_bond (a1, a2, v); dlist.addElement (dlb); } } if (showForces) { dlforce dlf = new dlforce (a1.x, a1.f, v); dlf.setForceMultiplier (forceMultiplier); dlist.addElement (dlf); } } if (dla != null) dla.paint (dlist, mypanel.getGraphics ()); else if (dlb != null) dlb.paint (dlist, mypanel.getGraphics ()); } private void enumerateTerms () { int i, j, k; if (!needToEnumerateTerms) return; needToEnumerateTerms = false; for (i = 0; i < atomList.size (); i++) ((atom) atomList.elementAt (i)).rehybridize (); termList = new Vector (); atom a = new carbon (); term t; t = new lterm (a, a); t.enumerate (atomList, termList); t = new aterm (a, a, a); t.enumerate (atomList, termList); t = new tterm (a, a, a, a); t.enumerate (atomList, termList); t = new lrterm (); t.enumerate (atomList, termList); } public void computeForces () { int i; enumerateTerms (); for (i = 0; i < atomList.size (); i++) ((atom) atomList.elementAt (i)).zeroForce (); for (i = 0; i < termList.size (); i++) ((term) termList.elementAt (i)).computeForces (); } public void energyMinimizeStep (double stepsize) { int i; computeForces (); for (i = 0; i < atomList.size (); i++) { int j; double flensq, m; atom a = (atom) atomList.elementAt (i); for (j = 0, flensq = 0.0; j < 3; j++) flensq += a.f[j] * a.f[j]; if (flensq > 0.0) { m = stepsize / Math.sqrt (flensq); for (j = 0; j < 3; j++) a.x[j] += m * a.f[j]; } } centerAtoms (); } }