core/vnl/vnl_quaternion.h

Go to the documentation of this file.
00001 // This is core/vnl/vnl_quaternion.h
00002 #ifndef vnl_quaternion_h_
00003 #define vnl_quaternion_h_
00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00005 #pragma interface
00006 #endif
00007 //:
00008 // \file
00009 // \brief Unit quaternion represents rotation in 3D.
00010 // \author awf@robots.ox.ac.uk
00011 // \date   16 Mar 00
00012 //
00013 // \verbatim
00014 //  Modifications
00015 //   20-05-2000 fsm. changed FLOAT to T since gcc will barf at
00016 //              the very reasonable forward declaration
00017 //              template <class FLOAT> class vnl_quaternion;
00018 //   23-3-2001 LSB (Manchester) Tidied documentation
00019 //   13-1-2003 Peter Vanroose - removed unimplemented method rotation_matrix()
00020 //   20-2-2006 Ian Scott - Added conversion to from Euler angles
00021 //   06-5-2006 Peter Vanroose - replaced all vnl_vector by vnl_vector_fixed
00022 // \endverbatim
00023 
00024 #include <vnl/vnl_vector_fixed.h>
00025 #include <vnl/vnl_matrix_fixed.h>
00026 #include <vcl_iostream.h>
00027 
00028 //: 4-element vector that represents rotation in 3D.
00029 // vnl_quaternion is a 4-element vector with 1 real and 3 imaginary
00030 // components:
00031 // \code
00032 //    q = r + (i*x + j*y + k*z)
00033 //    r = cos(theta/2)
00034 //    (x, y, z) = sin(theta/2) (kx, ky, kz)
00035 // \endcode
00036 // where theta and k are respectively the angle and axis of rotation.
00037 // 3D vectors can be thought of as imaginary quaternions, and so a
00038 // quaternion is represented as a vnl_vector_fixed<T,4> with the imaginary
00039 // part before the real part for 1-1 alignment.
00040 //
00041 // Unit quaternions provide a more efficient representation for
00042 // rotation, than the usual orthonormal matrix that has nine
00043 // parameters and six orthonormal constraints.  The unit
00044 // quaternion has only one unit magnitude constraint.  Composing
00045 // rotations with quaternions results in fewer multiplications
00046 // and less error.  To insure valid rotation results, the
00047 // nearest unit quaternion is computed, and this is much easier
00048 // than finding the nearest orthonormal matrix.  Transforming
00049 // vectors with a quaternion requires more operations compared
00050 // to multiplication with the equivalent orthonormal matrix.
00051 //
00052 // \sa
00053 // vnl_vector_fixed and vnl_matrix_fixed for basic operations on vectors and matrices.
00054 // \sa
00055 // Envelope for envelope-letter scheme that avoids deep copy on
00056 // return by value in arithmetic expressions like: q1 * q2 * q3 *...
00057 //
00058 
00059 export template <class T>
00060 class vnl_quaternion : public vnl_vector_fixed<T, 4>
00061 {
00062   typedef vnl_vector_fixed<T,4> Base;
00063  public:
00064 
00065   //: Constructor for null quaternion
00066   vnl_quaternion() {}
00067 
00068   //: Construct quaternion from components x,y,z,r
00069   vnl_quaternion(T x, T y, T z, T r);
00070 
00071   //: Construct quaternion from Euler Angles,
00072   // That is a rotation about the X axis, followed by Y, followed by
00073   // the Z axis, using a fixed reference frame.
00074   vnl_quaternion(T theta_X, T theta_Y, T theta_Z);
00075 
00076   //: Construct quaternion from axis and angle of rotation.
00077   // \note If you specify an angle in [0, 2pi], then methods angle() and axis() will return the same values.
00078   // However, if you specify an angle in [-2pi, 0], then methods angle() and axis() will return values with opposite signs.
00079   // \sa vnl_quaternion::angle()
00080   // \sa vnl_quaternion::axis()
00081   vnl_quaternion(vnl_vector_fixed<T,3> const& axis, T angle);
00082 
00083   //: Construct quaternion from from 3x3 row-major matrix
00084   explicit vnl_quaternion(vnl_matrix_fixed<T,3,3> const& transform);
00085 
00086   //: Construct quaternion from a 3D vector
00087   vnl_quaternion(vnl_vector_fixed<T,3> const& vec);
00088 
00089   //: Construct quaternion from a 4D vector
00090   vnl_quaternion (vnl_vector_fixed<T,4> const& vec);
00091 
00092   //: Copy constructor -- Creates a copy of from quaternion.
00093   inline vnl_quaternion(vnl_quaternion<T> const& from) : Base(from) {}
00094 
00095   //: Free internal array
00096   inline ~vnl_quaternion() {} // vnl_vector_fixed will free data array
00097 
00098   //:  Overloads assignment operator to copy rhs quaternion into lhs quaternion.
00099   inline vnl_quaternion& operator= (vnl_quaternion<T> const& rhs) { Base::operator=(rhs); return *this; }
00100 
00101   //: Imaginary component, parallel to axis of rotation.
00102   // Use this accessor to both get and set the component.
00103   inline T& x() { return this->operator()(0); }
00104   //: Imaginary component, parallel to axis of rotation.
00105   // Use this accessor to both get and set the component.
00106   inline T& y() { return this->operator()(1); }
00107   //: Imaginary component, parallel to axis of rotation.
00108   // Use this accessor to both get and set the component.
00109   inline T& z() { return this->operator()(2); }
00110   //: Real component.
00111   // Use this accessor to both get and set the component.
00112   inline T& r() { return this->operator()(3); }
00113 
00114   //: Imaginary component, parallel to axis of rotation.
00115   // Use this accessor to get the component.
00116   inline T x() const { return this->operator()(0); }
00117   //: Imaginary component, parallel to axis of rotation.
00118   // Use this accessor to get the component.
00119   inline T y() const { return this->operator()(1); }
00120   //: Imaginary component, parallel to axis of rotation.
00121   // Use this accessor to get the component.
00122   inline T z() const { return this->operator()(2); }
00123   //: Real component.
00124   // Use this accessor to get the component.
00125   inline T r() const { return this->operator()(3); }
00126 
00127   //: Copies and returns the real part.
00128   inline T real() const { return (*this)[3]; }
00129 
00130   //: Copies and returns the imaginary part.
00131   inline vnl_vector_fixed<T,3> imaginary() const { return this->extract(3,0); }
00132 
00133   //: Axis of rotation.
00134   // \note Axis not well defined for theta==0. In such a case (or if provided axis==(0,0,0)), this function returns (0,0,1).
00135   vnl_vector_fixed<T,3> axis() const;
00136 
00137   //: Angle of rotation.
00138   // \note Returned angle lies in [0, 2*pi]
00139   T angle() const;
00140 
00141   //: 3x3 rotation matrix
00142   vnl_matrix_fixed<T,3,3> rotation_matrix_transpose() const;
00143 
00144   //: 4x4 rotation matrix
00145   vnl_matrix_fixed<T,4,4> rotation_matrix_transpose_4() const;
00146 
00147   //: Same real, opposite img part
00148   vnl_quaternion<T> conjugate() const;
00149 
00150   //: Inverse for nonzero quat
00151   vnl_quaternion<T> inverse() const;
00152 
00153   vnl_quaternion<T> operator* (vnl_quaternion<T> const&) const;
00154 
00155   //: Rotate 3D v
00156   // The quaternion must be normalised first.
00157   vnl_vector_fixed<T,3> rotate(vnl_vector_fixed<T,3> const&) const;
00158 
00159   //: Rotation representation in Euler angles.
00160   // The angles raturned will be [theta_X,theta_Y,theta_Z]
00161   // where the final rotation is found be first applying theta_X radians
00162   // about the X axis, then theta_Y about the Y-axis, etc.
00163   // The axes stay in a fixed reference frame.
00164   // The quaternion mut be normalised first.
00165   vnl_vector_fixed<T,3> rotation_euler_angles() const;
00166 };
00167 
00168 //: operator<<
00169 // \relates vnl_quaternion
00170 template <class T>
00171 inline vcl_ostream& operator<< (vcl_ostream& os, vnl_quaternion<T> const& q)
00172 {
00173   return os << *((const vnl_vector_fixed<T,4>*) &q);
00174 }
00175 
00176 #define VNL_QUATERNION_INSTANTIATE(T) extern "Please #include <vnl/vnl_quaternion.txx> first"
00177 
00178 #endif // vnl_quaternion_h_

Generated on Fri Nov 21 05:06:14 2008 for core/vnl by  doxygen 1.5.1