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.Matrix3d;
024import javax.vecmath.Matrix4d;
025import javax.vecmath.Vector3d;
026
027import org.biojava.nbio.structure.jama.Matrix;
028
029/**
030 * Matrices contains static methods to operate and transform matrices used in 3D
031 * geometry (transformation matrices and rotation matrices).
032 * <p>
033 * This class complements and extends the functionallity of vecmath and JAMA.
034 * 
035 * @author Aleix Lafita
036 * @since 5.0.0
037 *
038 */
039public class Matrices {
040        
041        /** Prevent instantiation */
042        private Matrices(){}
043
044        /**
045         * Convert a transformation matrix into a JAMA rotation matrix. Because the
046         * JAMA matrix is a pre-multiplication matrix and the Vecmath matrix is a
047         * post-multiplication one, the rotation matrix is transposed to ensure that
048         * the transformation they produce is the same.
049         *
050         * @param transform
051         *            Matrix4d with transposed rotation matrix
052         * @return rotation matrix as JAMA object
053         */
054        public static Matrix getRotationJAMA(Matrix4d transform) {
055
056                Matrix rot = new Matrix(3, 3);
057                for (int i = 0; i < 3; i++) {
058                        for (int j = 0; j < 3; j++) {
059                                rot.set(j, i, transform.getElement(i, j)); // transposed
060                        }
061                }
062                return rot;
063        }
064        
065        /**
066         * Convert a transformation matrix into a rotation matrix.
067         *
068         * @param transform
069         *            Matrix4d
070         * @return rotation matrix
071         */
072        public static Matrix3d getRotationMatrix(Matrix4d transform) {
073
074                Matrix3d rot = new Matrix3d();
075                transform.setRotationScale(rot);
076                return rot;
077        }
078
079        /**
080         * Extract the translational vector of a transformation matrix.
081         *
082         * @param transform
083         *            Matrix4d
084         * @return Vector3d translation vector
085         */
086        public static Vector3d getTranslationVector(Matrix4d transform) {
087                Vector3d transl = new Vector3d();
088                transform.get(transl);
089                return transl;
090        }
091        
092        /**
093         * Convert JAMA rotation and translation to a Vecmath transformation matrix.
094         * Because the JAMA matrix is a pre-multiplication matrix and the Vecmath
095         * matrix is a post-multiplication one, the rotation matrix is transposed to
096         * ensure that the transformation they produce is the same.
097         *
098         * @param rot
099         *            3x3 Rotation matrix
100         * @param trans
101         *            3x1 Translation matrix
102         * @return 4x4 transformation matrix
103         */
104        public static Matrix4d getTransformation(Matrix rot, Matrix trans) {
105                return new Matrix4d(new Matrix3d(rot.getColumnPackedCopy()),
106                                new Vector3d(trans.getColumnPackedCopy()), 1.0);
107        }
108
109}