⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ringplacer.java

📁 化学图形处理软件
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* $RCSfile$     * $Author: egonw $     * $Date: 2007-08-28 11:16:54 +0200 (Tue, 28 Aug 2007) $     * $Revision: 8733 $ *  * Copyright (C) 1997-2007  The Chemistry Development Kit (CDK) project *  * Contact: cdk-devel@lists.sourceforge.net *  * 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. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. *  * 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.layout;import java.util.Iterator;import java.util.List;import java.util.Vector;import javax.vecmath.Point2d;import javax.vecmath.Vector2d;import org.openscience.cdk.CDKConstants;import org.openscience.cdk.geometry.GeometryToolsInternalCoordinates;import org.openscience.cdk.interfaces.IAtom;import org.openscience.cdk.interfaces.IAtomContainer;import org.openscience.cdk.interfaces.IBond;import org.openscience.cdk.interfaces.IMolecule;import org.openscience.cdk.interfaces.IRing;import org.openscience.cdk.interfaces.IRingSet;import org.openscience.cdk.tools.LoggingTool;import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;/** * Class providing methods for generating coordinates for ring atoms. * Various situations are supported, like condensation, spiro-attachment, etc. * They can be used for Automated Structure Diagram Generation or in the interactive * buildup of ringsystems by the user. *  * @cdk.module sdg **/public class RingPlacer {	final static boolean debug = false;	private LoggingTool logger;		private IMolecule molecule; 		private AtomPlacer atomPlacer = new AtomPlacer();		static int FUSED = 0;	static int BRIDGED = 1;			static int SPIRO = 2;	/**	 * The empty constructor.	 */	public RingPlacer() 	{		logger = new LoggingTool(this);	}	/**	 * Generated coordinates for a given ring. Multiplexes to special handlers 	 * for the different possible situations (spiro-, fusion-, bridged attachement)	 *	 * @param   ring  The ring to be placed	 * @param   sharedAtoms  The atoms of this ring, also members of another ring, which are already placed	 * @param   sharedAtomsCenter  The geometric center of these atoms	 * @param   ringCenterVector  A vector pointing the the center of the new ring	 * @param   bondLength  The standard bondlength	 */	public void placeRing(IRing ring, IAtomContainer sharedAtoms, Point2d sharedAtomsCenter, Vector2d ringCenterVector, double bondLength)	{		int sharedAtomCount = sharedAtoms.getAtomCount();		logger.debug("placeRing -> sharedAtomCount: " + sharedAtomCount);		if (sharedAtomCount > 2) 		{			placeBridgedRing(ring, sharedAtoms, sharedAtomsCenter, ringCenterVector, bondLength);		}		else if (sharedAtomCount == 2)		{			placeFusedRing(ring, sharedAtoms, sharedAtomsCenter, ringCenterVector, bondLength);		}		else if (sharedAtomCount == 1)		{			placeSpiroRing(ring, sharedAtoms, sharedAtomsCenter, ringCenterVector, bondLength);		}	}			/**	 * Positions the aliphatic substituents of a ring system	 *	 * @param   rs The RingSystem for which the substituents are to be laid out 	 * @return  A list of atoms that where laid out   	 */	public IAtomContainer placeRingSubstituents(IRingSet rs, double bondLength)	{		logger.debug("RingPlacer.placeRingSubstituents() start");		IRing ring = null;		IAtom atom = null;		IRingSet rings = null;		IAtomContainer unplacedPartners = rs.getBuilder().newAtomContainer();		IAtomContainer sharedAtoms = rs.getBuilder().newAtomContainer();		IAtomContainer primaryAtoms = rs.getBuilder().newAtomContainer();		IAtomContainer treatedAtoms = rs.getBuilder().newAtomContainer();		Point2d centerOfRingGravity = null;		for (int j = 0; j < rs.getAtomContainerCount(); j++)		{			ring = (IRing)rs.getAtomContainer(j); /* Get the j-th Ring in RingSet rs */			for (int k = 0; k < ring.getAtomCount(); k++)			{				unplacedPartners.removeAllElements();				sharedAtoms.removeAllElements();				primaryAtoms.removeAllElements();				atom = ring.getAtom(k);				rings = rs.getRings(atom);				centerOfRingGravity = GeometryToolsInternalCoordinates.get2DCenter(rings);				atomPlacer.partitionPartners(atom, unplacedPartners, sharedAtoms);				atomPlacer.markNotPlaced(unplacedPartners);				try				{						for (int f = 0; f < unplacedPartners.getAtomCount(); f++)						{							logger.debug("placeRingSubstituents->unplacedPartners: " + (molecule.getAtomNumber(unplacedPartners.getAtom(f)) + 1));						}				}				catch(Exception exc)				{				}								treatedAtoms.add(unplacedPartners);				if (unplacedPartners.getAtomCount() > 0)				{					atomPlacer.distributePartners(atom, sharedAtoms, centerOfRingGravity, unplacedPartners, bondLength);				}			}		}		logger.debug("RingPlacer.placeRingSubstituents() end");		return treatedAtoms;	}			/**	 * Generated coordinates for a given ring, which is connected to another ring a bridged ring, 	 * i.e. it shares more than two atoms with another ring.	 *	 * @param   ring  The ring to be placed	 * @param   sharedAtoms  The atoms of this ring, also members of another ring, which are already placed	 * @param   sharedAtomsCenter  The geometric center of these atoms	 * @param   ringCenterVector  A vector pointing the the center of the new ring	 * @param   bondLength  The standard bondlength	 */	private  void placeBridgedRing(IRing ring, IAtomContainer sharedAtoms, Point2d sharedAtomsCenter, Vector2d ringCenterVector, double bondLength )	{		double radius = getNativeRingRadius(ring, bondLength);		Point2d ringCenter = new Point2d(sharedAtomsCenter);		ringCenterVector.normalize();		logger.debug("placeBridgedRing->: ringCenterVector.length()" + ringCenterVector.length());			ringCenterVector.scale(radius);		ringCenter.add(ringCenterVector);		IAtom[] bridgeAtoms = getBridgeAtoms(sharedAtoms);		IAtom bondAtom1 = bridgeAtoms[0];		IAtom bondAtom2 = bridgeAtoms[1];		Vector2d bondAtom1Vector = new Vector2d(bondAtom1.getPoint2d());		Vector2d bondAtom2Vector = new Vector2d(bondAtom2.getPoint2d());				Vector2d originRingCenterVector = new Vector2d(ringCenter);				bondAtom1Vector.sub(originRingCenterVector);		bondAtom2Vector.sub(originRingCenterVector);				double occupiedAngle = bondAtom1Vector.angle(bondAtom2Vector);						double remainingAngle = (2 * Math.PI) - occupiedAngle;		double addAngle = remainingAngle / (ring.getRingSize() - sharedAtoms.getAtomCount() + 1);		logger.debug("placeBridgedRing->occupiedAngle: " + Math.toDegrees(occupiedAngle));		logger.debug("placeBridgedRing->remainingAngle: " + Math.toDegrees(remainingAngle));		logger.debug("placeBridgedRing->addAngle: " + Math.toDegrees(addAngle));						IAtom startAtom;		double centerX = ringCenter.x;		double centerY = ringCenter.y;				double xDiff = bondAtom1.getPoint2d().x - bondAtom2.getPoint2d().x;		double yDiff = bondAtom1.getPoint2d().y - bondAtom2.getPoint2d().y;				double startAngle;				int direction = 1;		// if bond is vertical		if (xDiff == 0)		{			logger.debug("placeBridgedRing->Bond is vertical");			//starts with the lower Atom			if (bondAtom1.getPoint2d().y > bondAtom2.getPoint2d().y)			{				startAtom = bondAtom1;			}			else			{				startAtom = bondAtom2;			}						//changes the drawing direction			if (centerX < bondAtom1.getPoint2d().x)			{				direction = 1;			}			else			{				direction = -1;			}		}		  // if bond is not vertical		else		{			//starts with the left Atom			if (bondAtom1.getPoint2d().x > bondAtom2.getPoint2d().x)			{				startAtom = bondAtom1;			}			else			{				startAtom = bondAtom2;			}						//changes the drawing direction			if (centerY - bondAtom1.getPoint2d().y > (centerX - bondAtom1.getPoint2d().x) * yDiff / xDiff)			{				direction = 1;			}			else			{				direction = -1;			}		}		startAngle = GeometryToolsInternalCoordinates.getAngle(startAtom.getPoint2d().x - ringCenter.x, startAtom.getPoint2d().y - ringCenter.y);		IAtom currentAtom = startAtom;        // determine first bond in Ring        int k = 0;//        for (k = 0; k < ring.getElectronContainerCount(); k++) {//            if (ring.getElectronContainer(k) instanceof IBond) break;//        }        IBond currentBond = sharedAtoms.getBond(0);		Vector atomsToDraw = new Vector();		for (int i = 0; i < ring.getBondCount(); i++)		{			currentBond = ring.getNextBond(currentBond, currentAtom);			currentAtom = currentBond.getConnectedAtom(currentAtom);			if (!sharedAtoms.contains(currentAtom))			{				atomsToDraw.addElement(currentAtom);			}		}			try			{				logger.debug("placeBridgedRing->atomsToPlace: " + atomPlacer.listNumbers(molecule, atomsToDraw));				logger.debug("placeBridgedRing->startAtom is: " + (molecule.getAtomNumber(startAtom) + 1));				logger.debug("placeBridgedRing->startAngle: " + Math.toDegrees(startAngle));				logger.debug("placeBridgedRing->addAngle: " + Math.toDegrees(addAngle));					}			catch(Exception exc)			{				logger.debug("Caught an exception while logging in RingPlacer");			}				addAngle = addAngle * direction;		atomPlacer.populatePolygonCorners(atomsToDraw, ringCenter, startAngle, addAngle, radius);	}		/**	 * Generated coordinates for a given ring, which is connected to a spiro ring.	 * The rings share exactly one atom.	 *	 * @param   ring  The ring to be placed	 * @param   sharedAtoms  The atoms of this ring, also members of another ring, which are already placed	 * @param   sharedAtomsCenter  The geometric center of these atoms	 * @param   ringCenterVector  A vector pointing the the center of the new ring	 * @param   bondLength  The standard bondlength	 */	public void placeSpiroRing(IRing ring, IAtomContainer sharedAtoms, Point2d sharedAtomsCenter, Vector2d ringCenterVector, double bondLength)	{		logger.debug("placeSpiroRing");		double radius = getNativeRingRadius(ring, bondLength);		Point2d ringCenter = new Point2d(sharedAtomsCenter);		ringCenterVector.normalize();		ringCenterVector.scale(radius);		ringCenter.add(ringCenterVector);		double addAngle = 2 * Math.PI / ring.getRingSize();		IAtom startAtom = sharedAtoms.getAtom(0);		//double centerX = ringCenter.x;		//double centerY = ringCenter.y;				//int direction = 1;		IAtom currentAtom = startAtom;		double startAngle = GeometryToolsInternalCoordinates.getAngle(startAtom.getPoint2d().x - ringCenter.x, startAtom.getPoint2d().y - ringCenter.y);		/* 		 * Get one bond connected to the spiro bridge atom.		 * It doesn't matter in which direction we draw.		 */ 		java.util.List bonds = ring.getConnectedBondsList(startAtom);				IBond currentBond = (IBond)bonds.get(0);				Vector atomsToDraw = new Vector();		/* 		 * Store all atoms to draw in consequtive order relative to the 		 * chosen bond.		 */ 		for (int i = 0; i < ring.getBondCount(); i++)		{			currentBond = ring.getNextBond(currentBond, currentAtom);			currentAtom = currentBond.getConnectedAtom(currentAtom);			atomsToDraw.addElement(currentAtom);		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -