Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Copyright (C) 1997-2007 Christoph Steinbeck
*
* Contact: [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
package org.openscience.cdk;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import javax.vecmath.Point2d;
import javax.vecmath.Point3d;
import java.io.Serializable;
import java.util.Iterator;
/**
* Implements the concept of a covalent bond between two or more atoms. A bond is
* considered to be a number of electrons connecting two or more of atoms.
*
* It should be noted that the majority of applications will consider 2-center bonds,
* especially since the bond orders currently supported are really only valid for
* 2-center bonds. However the code does support multi-center bonds, though the
* orders may not make sense at this point.
*
* In general code that assumes bonds are 2-centered can use this class seamlessly, as
* the semantics are identical to the older versions. Care shoud be exercised when
* using multi-center bonds using this class as the orders may not make sense.
*
* @author steinbeck
* @cdk.module data
* @cdk.githash
* @cdk.created 2003-10-02
* @cdk.keyword bond
* @cdk.keyword atom
* @cdk.keyword electron
*/
public class Bond extends ElectronContainer implements IBond, Serializable, Cloneable {
/**
* Determines if a de-serialized object is compatible with this class.
*
* This value must only be changed if and only if the new version
* of this class is incompatible with the old version. See Sun docs
* for details.
*/
private static final long serialVersionUID = 7057060562283387384L;
/**
* The bond order of this bond.
*/
protected IBond.Order order = (Order) CDKConstants.UNSET;
/**
* Number of atoms contained by this object.
*/
protected int atomCount = 0;
/**
* A list of atoms participating in this bond.
*/
protected IAtom[] atoms = null;
/**
* A descriptor the stereochemical orientation of this bond.
*/
protected IBond.Stereo stereo;
/**
* Constructs an empty bond.
*/
public Bond() {
this(null, null, null, IBond.Stereo.NONE);
atomCount = 0;
}
/**
* Constructs a bond with a single bond order..
*
* @param atom1 the first Atom in the bond
* @param atom2 the second Atom in the bond
*/
public Bond(IAtom atom1, IAtom atom2) {
this(atom1, atom2, IBond.Order.SINGLE, IBond.Stereo.NONE);
}
/**
* Constructs a bond with a given order.
*
* @param atom1 the first Atom in the bond
* @param atom2 the second Atom in the bond
* @param order the bond order
*/
public Bond(IAtom atom1, IAtom atom2, Order order) {
this(atom1, atom2, order, IBond.Stereo.NONE);
}
/**
* Constructs a multi-center bond, with undefined order and no stereo information.
*
* @param atoms An array of IAtom containing the atoms constituting the bond
*/
public Bond(IAtom[] atoms) {
this.atoms = new IAtom[atoms.length];
System.arraycopy(atoms, 0, this.atoms, 0, atoms.length);
atomCount = this.atoms.length;
}
/**
* Constructs a multi-center bond, with a specified order and no stereo information.
*
* @param atoms An array of IAtom containing the atoms constituting the bond
* @param order The order of the bond
*/
public Bond(IAtom[] atoms, Order order) {
this.atoms = new IAtom[atoms.length];
System.arraycopy(atoms, 0, this.atoms, 0, atoms.length);
atomCount = this.atoms.length;
this.order = order;
}
/**
* Constructs a bond with a given order and stereo orientation from an array
* of atoms.
*
* @param atom1 the first Atom in the bond
* @param atom2 the second Atom in the bond
* @param order the bond order
* @param stereo a descriptor the stereochemical orientation of this bond
*/
public Bond(IAtom atom1, IAtom atom2, Order order, IBond.Stereo stereo) {
atoms = new IAtom[2];
atoms[0] = atom1;
atoms[1] = atom2;
this.order = order;
updateElectronCount(order);
this.stereo = stereo;
this.atomCount = 2;
}
/**
* Returns the Iterator to atoms making up this bond.
* Iterator.remove() is not implemented.
*
* @return An Iterator to atoms participating in this bond
* @see #setAtoms
*/
@Override
public Iterable atoms() {
return new Iterable() {
@Override
public Iterator iterator() {
return new AtomsIterator();
}
};
}
/**
* {@inheritDoc}
*/
@Override
public int getIndex() {
return -1;
}
/**
* {@inheritDoc}
*/
@Override
public IAtomContainer getContainer() {
return null;
}
/**
* The inner Iterator class.
*/
private class AtomsIterator implements Iterator {
private int pointer = 0;
@Override
public boolean hasNext() {
return pointer < atomCount;
}
@Override
public IAtom next() {
++pointer;
return atoms[pointer - 1];
}
@Override
public void remove() {}
}
/**
* Sets the array of atoms making up this bond.
*
* @param atoms An array of atoms that forms this bond
* @see #atoms
*/
@Override
public void setAtoms(IAtom[] atoms) {
this.atoms = atoms;
atomCount = atoms.length;
notifyChanged();
}
/**
* Returns the number of Atoms in this Bond.
*
* @return The number of Atoms in this Bond
*/
@Override
public int getAtomCount() {
return atomCount;
}
/**
* Returns an Atom from this bond.
*
* @param position The position in this bond where the atom is
* @return The atom at the specified position, null if there are no atoms in the bond
* @see #setAtom
*/
@Override
public IAtom getAtom(int position) {
if (atoms == null)
return null;
else
return atoms[position];
}
/**
* {@inheritDoc}
*/
public IAtom getBegin() {
return atomCount < 1 ? null : atoms[0];
}
/**
* {@inheritDoc}
*/
public IAtom getEnd() {
return atomCount < 2 ? null : atoms[1];
}
/**
* {@inheritDoc}
*/
@Override
public IAtom getOther(IAtom atom) {
if (atoms[0].equals(atom))
return atoms[1];
else if (atoms[1].equals(atom))
return atoms[0];
return null;
}
/**
* {@inheritDoc}
*/
@Override
public IAtom getConnectedAtom(IAtom atom) {
return getOther(atom);
}
/**
* {@inheritDoc}
*/
@Override
public IAtom[] getConnectedAtoms(IAtom atom) {
if (atomCount < 1) return null;
IAtom[] connected = new IAtom[atomCount-1];
int j = 0;
for (int i = 0; i < atomCount; i++) {
if (!this.atoms[i].equals(atom)) {
if (j >= connected.length)
return null;
connected[j++] = this.atoms[i];
}
}
return connected;
}
/**
* Returns true if the given atom participates in this bond.
*
* @param atom The atom to be tested if it participates in this bond
* @return true if the atom participates in this bond
*/
@Override
public boolean contains(IAtom atom) {
if (atoms == null) return false;
for (IAtom localAtom : atoms) {
if (localAtom.equals(atom)) return true;
}
return false;
}
/**
* Sets an Atom in this bond.
*
* @param atom The atom to be set
* @param position The position in this bond where the atom is to be inserted
* @see #getAtom
*/
@Override
public void setAtom(IAtom atom, int position) {
if (atoms[position] == null && atom != null) atomCount++;
if (atoms[position] != null && atom == null) atomCount--;
atoms[position] = atom;
notifyChanged();
}
/**
* Returns the bond order of this bond.
*
* @return The bond order of this bond
* @see org.openscience.cdk.CDKConstants org.openscience.cdk.CDKConstants
* for predefined values.
* @see #setOrder
*/
@Override
public Order getOrder() {
return this.order;
}
/**
* Sets the bond order of this bond.
*
* @param order The bond order to be assigned to this bond
* @see org.openscience.cdk.CDKConstants
* org.openscience.cdk.CDKConstants for predefined values.
* @see #getOrder
*/
@Override
public void setOrder(Order order) {
this.order = order;
updateElectronCount(order);
notifyChanged();
}
private void updateElectronCount(Order order) {
if (order != null) {
switch (order) {
case SINGLE:
this.electronCount = 2;
break;
case DOUBLE:
this.electronCount = 4;
break;
case TRIPLE:
this.electronCount = 6;
break;
case QUADRUPLE:
this.electronCount = 8;
break;
case QUINTUPLE:
this.electronCount = 10;
break;
case SEXTUPLE:
this.electronCount = 12;
break;
default:
this.electronCount = 0;
break;
}
}
}
/**
* Returns the stereo descriptor for this bond.
*
* @return The stereo descriptor for this bond
* @see #setStereo
* @see org.openscience.cdk.CDKConstants for predefined values.
*/
@Override
public IBond.Stereo getStereo() {
return this.stereo;
}
/**
* Sets the stereo descriptor for this bond.
*
* @param stereo The stereo descriptor to be assigned to this bond.
* @see #getStereo
* @see org.openscience.cdk.CDKConstants for predefined values.
*/
@Override
public void setStereo(IBond.Stereo stereo) {
this.stereo = stereo;
notifyChanged();
}
/**
* Returns the geometric 2D center of the bond.
*
* @return The geometric 2D center of the bond
*/
@Override
public Point2d get2DCenter() {
double xOfCenter = 0;
double yOfCenter = 0;
for (IAtom atom : atoms) {
xOfCenter += atom.getPoint2d().x;
yOfCenter += atom.getPoint2d().y;
}
return new Point2d(xOfCenter / ((double) getAtomCount()), yOfCenter / ((double) getAtomCount()));
}
/**
* Returns the geometric 3D center of the bond.
*
* @return The geometric 3D center of the bond
*/
@Override
public Point3d get3DCenter() {
double xOfCenter = 0;
double yOfCenter = 0;
double zOfCenter = 0;
for (IAtom atom : atoms) {
xOfCenter += atom.getPoint3d().x;
yOfCenter += atom.getPoint3d().y;
zOfCenter += atom.getPoint3d().z;
}
return new Point3d(xOfCenter / getAtomCount(), yOfCenter / getAtomCount(), zOfCenter / getAtomCount());
}
/**
* Compares a bond with this bond.
*
* @param object Object of type Bond
* @return true if the bond is equal to this bond
*/
@Override
public boolean compare(Object object) {
if (object instanceof IBond) {
Bond bond = (Bond) object;
for (IAtom atom : atoms) {
if (!bond.contains(atom)) {
return false;
}
}
// not important ??!!
//if (order==bond.order)
// return false;
return true;
}
return false;
}
/**
* Checks whether a bond is connected to another one.
* This can only be true if the bonds have an Atom in common.
*
* @param bond The bond which is checked to be connect with this one
* @return true if the bonds share an atom, otherwise false
*/
@Override
public boolean isConnectedTo(IBond bond) {
for (IAtom atom : atoms) {
if (bond.contains(atom)) return true;
}
return false;
}
/** {@inheritDoc} */
@Override
public boolean isAromatic() {
return getFlag(CDKConstants.ISAROMATIC);
}
/** {@inheritDoc} */
@Override
public void setIsAromatic(boolean arom) {
setFlag(CDKConstants.ISAROMATIC, arom);
}
/** {@inheritDoc} */
@Override
public boolean isInRing() {
return getFlag(CDKConstants.ISINRING);
}
/** {@inheritDoc} */
@Override
public void setIsInRing(boolean ring) {
setFlag(CDKConstants.ISINRING, ring);
}
/**
* Clones this bond object, including clones of the atoms between which the
* bond is defined.
*
* @return The cloned object
*/
@Override
public IBond clone() throws CloneNotSupportedException {
Bond clone = (Bond) super.clone();
// clone all the Atoms
if (atoms != null) {
clone.atoms = new IAtom[atoms.length];
for (int f = 0; f < atoms.length; f++) {
if (atoms[f] != null) {
clone.atoms[f] = (IAtom) ((IAtom) atoms[f]).clone();
}
}
}
return clone;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return super.hashCode();
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (obj instanceof BondRef)
return super.equals(((BondRef) obj).deref());
return super.equals(obj);
}
/**
* Returns a one line string representation of this Container. This method is
* conform RFC #9.
*
* @return The string representation of this Container
*/
@Override
public String toString() {
StringBuffer resultString = new StringBuffer(32);
resultString.append("Bond(").append(this.hashCode());
if (getOrder() != null) {
resultString.append(", #O:").append(getOrder());
}
resultString.append(", #S:").append(getStereo());
if (getAtomCount() > 0) {
resultString.append(", #A:").append(getAtomCount());
for (int i = 0; i < atomCount; i++) {
resultString.append(", ").append(atoms[i] == null ? "null" : atoms[i].toString());
}
}
resultString.append(", ").append(super.toString());
resultString.append(')');
return resultString.toString();
}
}