001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.geometry; 022 023import javax.vecmath.*; 024 025/** 026 * The SuperPositionQuat implements a quaternion based algorithm to superpose 027 * arrays of Points in 3D. 028 * 029 * @author Peter Rose 030 * @author Aleix Lafita 031 * 032 */ 033public final class SuperPositionQuat extends SuperPositionAbstract { 034 035 /** 036 * Constructor for the quaternion based superposition algorithm. 037 * 038 * @param centered 039 * true if the point arrays are centered at the origin (faster), 040 * false otherwise 041 */ 042 public SuperPositionQuat(boolean centered) { 043 super(centered); 044 } 045 046 @Override 047 public Matrix4d superpose(Point3d[] fixed, Point3d[] moved) { 048 049 checkInput(fixed, moved); 050 051 if (centered) { 052 Quat4d q = UnitQuaternions.relativeOrientation(fixed, moved); 053 Matrix4d rotTrans = new Matrix4d(); 054 rotTrans.set(q); 055 return rotTrans; 056 } 057 058 // translate to origin 059 Point3d[] xref = CalcPoint.clonePoint3dArray(fixed); 060 Point3d xtrans = CalcPoint.centroid(xref); 061 xtrans.negate(); 062 CalcPoint.translate(new Vector3d(xtrans), xref); 063 064 Point3d[] yref = CalcPoint.clonePoint3dArray(moved); 065 Point3d ytrans = CalcPoint.centroid(yref); 066 ytrans.negate(); 067 CalcPoint.translate(new Vector3d(ytrans), yref); 068 069 // calculate rotational component (rotation around origin) 070 Quat4d q = UnitQuaternions.relativeOrientation(xref, yref); 071 Matrix4d rotTrans = new Matrix4d(); 072 rotTrans.set(q); 073 074 // combine with moved -> origin translation 075 Matrix4d trans = new Matrix4d(); 076 trans.setIdentity(); 077 trans.setTranslation(new Vector3d(ytrans)); 078 rotTrans.mul(rotTrans, trans); 079 080 // combine with origin -> fixed translation 081 xtrans.negate(); 082 Matrix4d transInverse = new Matrix4d(); 083 transInverse.setIdentity(); 084 transInverse.setTranslation(new Vector3d(xtrans)); 085 rotTrans.mul(transInverse, rotTrans); 086 087 return rotTrans; 088 089 } 090 091 @Override 092 public double getRmsd(Point3d[] x, Point3d[] y) { 093 Point3d[] yclone = CalcPoint.clonePoint3dArray(y); 094 superposeAndTransform(x, yclone); 095 return CalcPoint.rmsd(x, yclone); 096 } 097 098}