📄 geometrytoolsinternalcoordinates.java
字号:
/* * $RCSfile$ * $Author: miguelrojasch $ * $Date: 2006-09-27 13:32:31 +0000 (Mi, 27 Sep 2006) $ * $Revision: 7069 $ * * 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.geometry;import org.openscience.cdk.CDKConstants;import org.openscience.cdk.exception.CDKException;import org.openscience.cdk.interfaces.IAtom;import org.openscience.cdk.interfaces.IAtomContainer;import org.openscience.cdk.interfaces.IBond;import org.openscience.cdk.interfaces.IRingSet;import org.openscience.cdk.isomorphism.UniversalIsomorphismTester;import org.openscience.cdk.isomorphism.mcss.RMap;import org.openscience.cdk.tools.LoggingTool;import javax.vecmath.Point2d;import javax.vecmath.Point3d;import javax.vecmath.Vector2d;import javax.vecmath.Vector3d;import java.awt.*;import java.util.*;import java.util.List;/** * A set of static utility classes for geometric calculations and operations. * This class is extensively used, for example, by JChemPaint to edit molecule. * All methods in this class change the coordinates of the atoms. Use GeometryTools if you use an external set of coordinates (e. g. rendeirngCoordinates from RendererModel) * * @author seb * @author Stefan Kuhn * @author Egon Willighagen * @author Ludovic Petain * @author Christian Hoppe * * @cdk.module standard */public class GeometryToolsInternalCoordinates { private static LoggingTool logger = new LoggingTool(GeometryToolsInternalCoordinates.class); /** * Adds an automatically calculated offset to the coordinates of all atoms * such that all coordinates are positive and the smallest x or y coordinate * is exactly zero. * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon AtomContainer for which all the atoms are translated to * positive coordinates */ public static void translateAllPositive(IAtomContainer atomCon) { double minX = Double.MAX_VALUE; double minY = Double.MAX_VALUE; java.util.Iterator atoms = atomCon.atoms(); while (atoms.hasNext()) { IAtom atom = (IAtom)atoms.next(); if (atom.getPoint2d() != null) { if (atom.getPoint2d().x < minX) { minX = atom.getPoint2d().x; } if (atom.getPoint2d().y < minY) { minY = atom.getPoint2d().y; } } } logger.debug("Translating: minx=" + minX + ", minY=" + minY); translate2D(atomCon, minX * -1, minY * -1); } /** * Translates the given molecule by the given Vector. * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon The molecule to be translated *@param transX translation in x direction *@param transY translation in y direction */ public static void translate2D(IAtomContainer atomCon, double transX, double transY) { translate2D(atomCon, new Vector2d(transX, transY)); } /** * Scales a molecule such that it fills a given percentage of a given * dimension * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon The molecule to be scaled *@param areaDim The dimension to be filled *@param fillFactor The percentage of the dimension to be filled */ public static void scaleMolecule(IAtomContainer atomCon, Dimension areaDim, double fillFactor) { Dimension molDim = get2DDimension(atomCon); double widthFactor = (double) areaDim.width / (double) molDim.width; double heightFactor = (double) areaDim.height / (double) molDim.height; double scaleFactor = Math.min(widthFactor, heightFactor) * fillFactor; scaleMolecule(atomCon, scaleFactor); } /** * Multiplies all the coordinates of the atoms of the given molecule with the * scalefactor. * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon The molecule to be scaled *@param scaleFactor Description of the Parameter */ public static void scaleMolecule(IAtomContainer atomCon, double scaleFactor) { for (int i = 0; i < atomCon.getAtomCount(); i++) { if (atomCon.getAtom(i).getPoint2d() != null) { atomCon.getAtom(i).getPoint2d().x *= scaleFactor; atomCon.getAtom(i).getPoint2d().y *= scaleFactor; } } } /** * Centers the molecule in the given area * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon molecule to be centered *@param areaDim dimension in which the molecule is to be centered */ public static void center(IAtomContainer atomCon, Dimension areaDim) { Dimension molDim = get2DDimension(atomCon); int transX = (areaDim.width - molDim.width) / 2; int transY = (areaDim.height - molDim.height) / 2; translateAllPositive(atomCon); translate2D(atomCon, new Vector2d(transX, transY)); } /** * Translates a molecule from the origin to a new point denoted by a vector. * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon molecule to be translated *@param vector dimension that represents the translation vector */ public static void translate2D(IAtomContainer atomCon, Vector2d vector) { java.util.Iterator atoms = atomCon.atoms(); while (atoms.hasNext()) { IAtom atom = (IAtom)atoms.next(); if (atom.getPoint2d() != null) { atom.getPoint2d().add(vector); } else { logger.warn("Could not translate atom in 2D space"); } } } /** * Rotates a molecule around a given center by a given angle * *@param atomCon The molecule to be rotated *@param center A point giving the rotation center *@param angle The angle by which to rotate the molecule, in radians */ public static void rotate(IAtomContainer atomCon, Point2d center, double angle) { Point2d p; double costheta = Math.cos(angle); double sintheta = Math.sin(angle); IAtom atom; for (int i = 0; i < atomCon.getAtomCount(); i++) { atom = atomCon.getAtom(i); p = atom.getPoint2d(); double x = p.x - center.x; double y = p.y - center.y; p.x = x * costheta - y * sintheta + center.x; p.y = x * sintheta + y * costheta + center.y; } } /** * Rotates a 3D point about a specified line segment by a specified angle. * * The code is based on code available <a href="http://astronomy.swin.edu.au/~pbourke/geometry/rotate/source.c">here</a>. * Positive angles are anticlockwise looking down the axis towards the origin. * Assume right hand coordinate system. * * @param atom The atom to rotate * @param p1 The first point of the line segment * @param p2 The second point of the line segment * @param angle The angle to rotate by (in degrees) */ public static void rotate(IAtom atom, Point3d p1, Point3d p2, double angle) { double costheta, sintheta; Point3d r = new Point3d(); r.x = p2.x - p1.x; r.y = p2.y - p1.y; r.z = p2.z - p1.z; normalize(r); angle = angle * Math.PI / 180.0; costheta = Math.cos(angle); sintheta = Math.sin(angle); Point3d p = atom.getPoint3d(); p.x -= p1.x; p.y -= p1.y; p.z -= p1.z; Point3d q = new Point3d(0, 0, 0); q.x += (costheta + (1 - costheta) * r.x * r.x) * p.x; q.x += ((1 - costheta) * r.x * r.y - r.z * sintheta) * p.y; q.x += ((1 - costheta) * r.x * r.z + r.y * sintheta) * p.z; q.y += ((1 - costheta) * r.x * r.y + r.z * sintheta) * p.x; q.y += (costheta + (1 - costheta) * r.y * r.y) * p.y; q.y += ((1 - costheta) * r.y * r.z - r.x * sintheta) * p.z; q.z += ((1 - costheta) * r.x * r.z - r.y * sintheta) * p.x; q.z += ((1 - costheta) * r.y * r.z + r.x * sintheta) * p.y; q.z += (costheta + (1 - costheta) * r.z * r.z) * p.z; q.x += p1.x; q.y += p1.y; q.z += p1.z; atom.setPoint3d(q); } /** * Normalizes a point. * * @param point The point to normalize */ public static void normalize(Point3d point) { double sum = Math.sqrt(point.x * point.x + point.y * point.y + point.z * point.z); point.x = point.x / sum; point.y = point.y / sum; point.z = point.z / sum; } /** * Returns the java.awt.Dimension of a molecule * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon of which the dimension should be returned *@return The java.awt.Dimension of this molecule */ public static Dimension get2DDimension(IAtomContainer atomCon) { double[] minmax = getMinMax(atomCon); double maxX = minmax[2]; double maxY = minmax[3]; double minX = minmax[0]; double minY = minmax[1]; return new Dimension((int) (maxX - minX + 1), (int) (maxY - minY + 1)); } /** * Returns the minimum and maximum X and Y coordinates of the atoms in the * AtomContainer. The output is returned as: <pre> * minmax[0] = minX; * minmax[1] = minY; * minmax[2] = maxX; * minmax[3] = maxY; * </pre> * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param container Description of the Parameter *@return An four int array as defined above. */ public static double[] getMinMax(IAtomContainer container) { double maxX = Double.MIN_VALUE; double maxY = Double.MIN_VALUE; double minX = Double.MAX_VALUE; double minY = Double.MAX_VALUE; for (int i = 0; i < container.getAtomCount(); i++) { IAtom atom = container.getAtom(i); if (atom.getPoint2d() != null) { if (atom.getPoint2d().x > maxX) { maxX = atom.getPoint2d().x; } if (atom.getPoint2d().x < minX) { minX = atom.getPoint2d().x; } if (atom.getPoint2d().y > maxY) { maxY = atom.getPoint2d().y; } if (atom.getPoint2d().y < minY) { minY = atom.getPoint2d().y; } } } double[] minmax = new double[4]; minmax[0] = minX; minmax[1] = minY; minmax[2] = maxX; minmax[3] = maxY; return minmax; } /** * Translates a molecule from the origin to a new point denoted by a vector. * See comment for center(IAtomContainer atomCon, Dimension areaDim, HashMap renderingCoordinates) for details on coordinate sets * *@param atomCon molecule to be translated *@param p Description of the Parameter */ public static void translate2DCentreOfMassTo(IAtomContainer atomCon, Point2d p) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -