/vol/vipdata/irtk/geometry++/include/irtkQuaternion.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkQuaternion.h 2 2008-12-23 12:40:14Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2008-12-23 12:40:14 +0000 (Tue, 23 Dec 2008) $
00008   Version   : $Revision: 2 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifndef _IRTKQUATERNION_H
00014 
00015 #define _IRTKQUATERNION_H
00016 
00017 #include <irtkCommon.h>
00018 #include <irtkGeometry.h>
00019 
00021 class irtkQuaternion : public irtkObject
00022 {
00023 public:
00025   double _t;
00026 
00028   double _u;
00029 
00031   double _v;
00032 
00034   double _w;
00035 
00037   irtkQuaternion();
00038 
00040   irtkQuaternion(double t, double u, double v, double w);
00041 
00043   irtkQuaternion(const irtkQuaternion& q);
00044 
00046   irtkQuaternion& operator=(const irtkQuaternion& q);
00047 
00049   friend irtkQuaternion operator+(const irtkQuaternion& a, const irtkQuaternion& b);
00050 
00052   friend irtkQuaternion operator-(const irtkQuaternion& a, const irtkQuaternion& b);
00053 
00055   friend irtkQuaternion operator*(const irtkQuaternion& a, const irtkQuaternion& b);
00056 
00058   friend irtkQuaternion operator*(const irtkQuaternion& a, double b);
00059 
00061   friend ostream& operator<<(ostream& os, const irtkQuaternion& q);
00062 
00064   irtkQuaternion Conjugate() const;
00065 
00067   irtkQuaternion Inverse() const;
00068 
00070   void Normalize();
00071 
00073   double Length() const;
00074 
00077   irtkMatrix ComputeRotationMatrix() const;
00078 
00085   static irtkMatrix ComputeTransformationMatrix(double alpha,
00086       double u, double v, double w, double ox, double oy, double oz);
00087 
00093   static irtkMatrix ComputeRotationMatrix(double alpha, double u, double v, double w);
00094 
00099   static irtkQuaternion ComputeRotationQuaternion(double alpha, double u, double v, double w);
00100 
00102   virtual const char* NameOfClass();
00103 };
00104 
00105 inline irtkQuaternion::irtkQuaternion()
00106 {
00107   _t = 0;
00108   _u = 0;
00109   _v = 0;
00110   _w = 0;
00111 }
00112 
00113 inline irtkQuaternion::irtkQuaternion(double t, double u, double v, double w)
00114 {
00115   _t = t;
00116   _u = u;
00117   _v = v;
00118   _w = w;
00119 }
00120 
00121 inline irtkQuaternion::irtkQuaternion(const irtkQuaternion& q)
00122 {
00123   _t = q._t;
00124   _u = q._u;
00125   _v = q._v;
00126   _w = q._w;
00127 }
00128 
00129 inline irtkQuaternion& irtkQuaternion::operator=(const irtkQuaternion& q)
00130 {
00131   if (&q != this) {
00132     _t = q._t;
00133     _u = q._u;
00134     _v = q._v;
00135     _w = q._w;
00136   }
00137 
00138   return *this;
00139 }
00140 
00141 inline irtkQuaternion operator+(const irtkQuaternion& a, const irtkQuaternion& b)
00142 {
00143   irtkQuaternion q;
00144 
00145   q._t = a._t + b._t;
00146   q._u = a._u + b._u;
00147   q._v = a._v + b._v;
00148   q._w = a._w + b._w;
00149 
00150   return q;
00151 }
00152 
00153 inline irtkQuaternion operator-(const irtkQuaternion& a, const irtkQuaternion& b)
00154 {
00155   irtkQuaternion q;
00156 
00157   q._t = a._t - b._t;
00158   q._u = a._u - b._u;
00159   q._v = a._v - b._v;
00160   q._w = a._w - b._w;
00161 
00162   return q;
00163 }
00164 
00165 inline irtkQuaternion operator*(const irtkQuaternion& a, const irtkQuaternion& b)
00166 {
00167   irtkQuaternion q;
00168 
00169   q._t = a._t*b._t - a._u*b._u - a._v*b._v - a._w*b._w;
00170   q._u = a._t*b._u + a._u*b._t + a._v*b._w - a._w*b._v;
00171   q._v = a._t*b._v - a._u*b._w + a._v*b._t + a._w*b._u;
00172   q._w = a._t*b._w + a._u*b._v - a._v*b._u + a._w*b._t;
00173 
00174   return q;
00175 }
00176 
00177 inline irtkQuaternion operator*(const irtkQuaternion& a, double b)
00178 {
00179   irtkQuaternion q;
00180 
00181   q._t = a._t*b;
00182   q._u = a._u*b;
00183   q._v = a._v*b;
00184   q._w = a._w*b;
00185 
00186   return q;
00187 }
00188 
00189 inline ostream& operator<<(ostream& os, const irtkQuaternion& q)
00190 {
00191   os << "_t = " << q._t << " _u = " << q._u << " _v = " << q._v << " _w = " << q._w;
00192 
00193   return os;
00194 }
00195 
00196 inline irtkQuaternion irtkQuaternion::Conjugate() const
00197 {
00198   irtkQuaternion q;
00199 
00200   q._t = _t;
00201   q._u = -_u;
00202   q._v = -_v;
00203   q._w = -_w;
00204 
00205   return q;
00206 }
00207 
00208 inline irtkQuaternion irtkQuaternion::Inverse() const
00209 {
00210   irtkQuaternion q = Conjugate();
00211 
00212   double lenq = q.Length();
00213   q = q*(1.0/(lenq*lenq));
00214 
00215   return q;
00216 }
00217 
00218 inline void irtkQuaternion::Normalize()
00219 {
00220   double length = Length();
00221 
00222   if (length > 0) {
00223     _t /= length;
00224     _u /= length;
00225     _v /= length;
00226     _w /= length;
00227   }
00228 }
00229 
00230 inline double irtkQuaternion::Length() const
00231 {
00232   return sqrt(_t*_t + _u*_u + _v*_v + _w*_w);
00233 }
00234 
00235 inline const char* irtkQuaternion::NameOfClass()
00236 {
00237   return "irtkQuaternion";
00238 }
00239 
00240 #endif // __IRTKQUATERNION_H