Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

VMDQuat.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: VMDQuat.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.11 $      $Date: 2010/12/16 04:08:46 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Quaternion class used by tracker/tool code 
00019  ***************************************************************************/
00020 
00021 #include <math.h>
00022 #include "VMDQuat.h"
00023 #include "utilities.h"
00024 
00025 void Quat::identity() {
00026   qx = qy = qz = 0;
00027   qw = 1;
00028 }
00029 
00030 Quat::Quat(double x, double y, double z, double w) {
00031   qx = x;
00032   qy = y;
00033   qz = z;
00034   qw = w;
00035 }
00036 
00037 void Quat::rotate(const float *u, float angle) {
00038   Quat q;
00039   double theta = DEGTORAD(angle);
00040   q.qw = cos(0.5*theta);
00041   double sintheta = sin(0.5*theta);
00042   q.qx = u[0]*sintheta;
00043   q.qy = u[1]*sintheta;
00044   q.qz = u[2]*sintheta;
00045   mult(q);
00046 }
00047 
00048 void Quat::rotate(char axis, float angle) {
00049   Quat q;
00050   double theta = DEGTORAD(angle);
00051   q.qw = cos(0.5*theta);
00052   double sintheta = sin(0.5*theta);
00053   switch(axis) {
00054     case 'x': q.qx = sintheta; q.qy = q.qz = 0; break;
00055     case 'y': q.qy = sintheta; q.qz = q.qx = 0; break;
00056     case 'z': q.qz = sintheta; q.qx = q.qy = 0; break;
00057   }
00058   mult(q); 
00059 }
00060 
00061 void Quat::invert() {
00062   qx = -qx;
00063   qy = -qy;
00064   qz = -qz;
00065 }
00066 
00067 void Quat::mult(const Quat &q) {
00068   double x,y,z,w;
00069   w = q.qw*qw - q.qx*qx - q.qy*qy - q.qz*qz;
00070   x = q.qw*qx + q.qx*qw + q.qy*qz - q.qz*qy;
00071   y = q.qw*qy - q.qx*qz + q.qy*qw + q.qz*qx;
00072   z = q.qw*qz + q.qx*qy - q.qy*qx + q.qz*qw;
00073   qw = w;
00074   qx = x;
00075   qy = y;
00076   qz = z;
00077 }
00078 
00079 void Quat::multpoint3(const float *p, float *out) const {
00080   Quat pquat(p[0], p[1], p[2], 0);
00081   Quat inv(-qx, -qy, -qz, qw);
00082   inv.mult(pquat);
00083   inv.mult(*this);
00084   out[0] = (float) inv.qx;
00085   out[1] = (float) inv.qy;
00086   out[2] = (float) inv.qz;
00087 }
00088 
00089 void Quat::printQuat(float *q) {
00090   q[0] = (float) qx;
00091   q[1] = (float) qy;
00092   q[2] = (float) qz;
00093   q[3] = (float) qw;
00094 }
00095 
00096 void Quat::printMatrix(float *m) {
00097   m[0] = (float) (qw*qw + qx*qx - qy*qy -qz*qz);
00098   m[1] = (float) (2*(qx*qy + qw*qz));
00099   m[2] = (float) (2*(qx*qz - qw*qy));
00100 
00101   m[4] = (float) (2*(qx*qy - qw*qz));
00102   m[5] = (float) (qw*qw - qx*qx + qy*qy - qz*qz);
00103   m[6] = (float) (2*(qy*qz + qw*qx));
00104   
00105   m[8] = (float) (2*(qx*qz + qw*qy));
00106   m[9] = (float) (2*(qy*qz - qw*qx));
00107   m[10]= (float) (qw*qw - qx*qx - qy*qy + qz*qz);
00108   
00109   m[15]= (float) (qw*qw + qx*qx + qy*qy + qz*qz);
00110   
00111   m[3] = m[7] = m[11] = m[12] = m[13] = m[14] = 0;
00112 }
00113 
00114 static int perm[3] = {1,2,0};
00115 #define mat(a,b) (m[4*a+b])
00116 
00117 void Quat::fromMatrix(const float *m) {
00118   float T = mat(0,0) + mat(1,1) + mat(2,2);
00119   if (T > 0) { // w is the largest element in the quat
00120     double iw = sqrt(T+1.0);
00121     qw = iw * 0.5; 
00122     iw = 0.5/iw;
00123     qx = (mat(1,2) - mat(2,1)) * iw;
00124     qy = (mat(2,0) - mat(0,2)) * iw;
00125     qz = (mat(0,1) - mat(1,0)) * iw;
00126   } else {     // Find the largest diagonal element
00127     int i,j,k;
00128     double &qi = qx, &qj = qy, &qk = qz;
00129     i=0;
00130     if (mat(1,1) > mat(0,0)) {i=1; qi = qy; qj = qz; qk = qx; }
00131     if (mat(2,2) > mat(i,i)) {i=2; qi = qz; qj = qx; qk = qy; }
00132     j=perm[i];
00133     k=perm[j];
00134  
00135     double iqi = sqrt( (mat(i,i) - (mat(j,j) + mat(k,k))) + 1.0);
00136     qi = iqi * 0.5;
00137     iqi = 0.5/iqi;
00138    
00139     qw = (mat(j,k) - mat(k,j))*iqi;
00140     qj = (mat(i,j) + mat(j,i))*iqi;
00141     qk = (mat(i,k) + mat(k,i))*iqi;
00142   }
00143 }
00144  

Generated on Wed May 23 01:50:31 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002