/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.nbio.structure.geometry; import javax.vecmath.*; /** * The SuperPositionQuat implements a quaternion based algorithm to superpose * arrays of Points in 3D. * * @author Peter Rose * @author Aleix Lafita * */ public final class SuperPositionQuat extends SuperPositionAbstract { /** * Constructor for the quaternion based superposition algorithm. * * @param centered * true if the point arrays are centered at the origin (faster), * false otherwise */ public SuperPositionQuat(boolean centered) { super(centered); } @Override public Matrix4d superpose(Point3d[] fixed, Point3d[] moved) { checkInput(fixed, moved); if (centered) { Quat4d q = UnitQuaternions.relativeOrientation(fixed, moved); Matrix4d rotTrans = new Matrix4d(); rotTrans.set(q); return rotTrans; } // translate to origin Point3d[] xref = CalcPoint.clonePoint3dArray(fixed); Point3d xtrans = CalcPoint.centroid(xref); xtrans.negate(); CalcPoint.translate(new Vector3d(xtrans), xref); Point3d[] yref = CalcPoint.clonePoint3dArray(moved); Point3d ytrans = CalcPoint.centroid(yref); ytrans.negate(); CalcPoint.translate(new Vector3d(ytrans), yref); // calculate rotational component (rotation around origin) Quat4d q = UnitQuaternions.relativeOrientation(xref, yref); Matrix4d rotTrans = new Matrix4d(); rotTrans.set(q); // combine with moved -> origin translation Matrix4d trans = new Matrix4d(); trans.setIdentity(); trans.setTranslation(new Vector3d(ytrans)); rotTrans.mul(rotTrans, trans); // combine with origin -> fixed translation xtrans.negate(); Matrix4d transInverse = new Matrix4d(); transInverse.setIdentity(); transInverse.setTranslation(new Vector3d(xtrans)); rotTrans.mul(transInverse, rotTrans); return rotTrans; } @Override public double getRmsd(Point3d[] x, Point3d[] y) { Point3d[] yclone = CalcPoint.clonePoint3dArray(y); superposeAndTransform(x, yclone); return CalcPoint.rmsd(x, yclone); } }