| 1 |
|
/*========================================================================= |
| 2 |
|
|
| 3 |
|
Program: Insight Segmentation & Registration Toolkit |
| 4 |
|
Module: $RCSfile: itkVersor.h.html,v $ |
| 5 |
|
Language: C++ |
| 6 |
|
Date: $Date: 2006/01/17 19:15:49 $ |
| 7 |
|
Version: $Revision: 1.4 $ |
| 8 |
|
|
| 9 |
|
Copyright (c) Insight Software Consortium. All rights reserved. |
| 10 |
|
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. |
| 11 |
|
|
| 12 |
|
This software is distributed WITHOUT ANY WARRANTY; without even |
| 13 |
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 |
|
PURPOSE. See the above copyright notices for more information. |
| 15 |
|
|
| 16 |
|
=========================================================================*/ |
| 17 |
|
#ifndef __itkVersor_h |
| 18 |
|
#define __itkVersor_h |
| 19 |
|
|
| 20 |
|
#include "itkVector.h" |
| 21 |
|
#include "itkPoint.h" |
| 22 |
|
#include "itkMatrix.h" |
| 23 |
|
#include "itkCovariantVector.h" |
| 24 |
|
#include "vnl/vnl_quaternion.h" |
| 25 |
|
#include "vnl/vnl_vector_fixed.h" |
| 26 |
|
|
| 27 |
|
namespace itk |
| 28 |
|
{ |
| 29 |
|
|
| 30 |
|
/** \class Versor |
| 31 |
|
* \brief A templated class holding a unit quaternion. |
| 32 |
|
* |
| 33 |
|
* Versor is a templated class that holds a unit quaternion. |
| 34 |
|
* The difference between versors and quaternions is that quaternions |
| 35 |
|
* can represent rotations and scale changes while versors are limited |
| 36 |
|
* to rotations. |
| 37 |
|
* |
| 38 |
|
* This class only implements the operations that maintain versors as |
| 39 |
|
* a group, that is, any operations between versors result in another |
| 40 |
|
* versor. For this reason, addition is not defined in this class, even |
| 41 |
|
* though it is a valid operation between quaternions. |
| 42 |
|
* |
| 43 |
|
* \ingroup Geometry |
| 44 |
|
* \ingroup DataRepresentation |
| 45 |
|
* |
| 46 |
|
* \sa Vector |
| 47 |
|
* \sa Point |
| 48 |
|
* \sa CovariantVector |
| 49 |
|
* \sa Matrix |
| 50 |
|
*/ |
| 51 |
|
template<class T> |
| 52 |
|
class Versor |
| 53 |
|
{ |
| 54 |
|
public: |
| 55 |
|
/** Standard class typedefs. */ |
| 56 |
|
typedef Versor Self; |
| 57 |
|
|
| 58 |
|
/** ValueType can be used to declare a variable that is the same type |
| 59 |
|
* as a data element held in a Versor. */ |
| 60 |
|
typedef T ValueType; |
| 61 |
|
|
| 62 |
|
/** Type used for computations on the versor components */ |
| 63 |
|
typedef typename NumericTraits<ValueType>::RealType RealType; |
| 64 |
|
|
| 65 |
|
/** Vector type used to represent the axis. */ |
| 66 |
|
typedef Vector<T,3> VectorType; |
| 67 |
|
|
| 68 |
|
/** Point type. */ |
| 69 |
|
typedef Point<T,3> PointType; |
| 70 |
|
|
| 71 |
|
/** CovariantVector type. */ |
| 72 |
|
typedef CovariantVector<T,3> CovariantVectorType; |
| 73 |
|
|
| 74 |
|
/** Vnl Vector type. */ |
| 75 |
|
typedef vnl_vector_fixed<T,3> VnlVectorType; |
| 76 |
|
|
| 77 |
|
/** Vnl Quaternion type. */ |
| 78 |
|
typedef vnl_quaternion<T> VnlQuaternionType; |
| 79 |
|
|
| 80 |
|
/** Type of the rotation matrix equivalent to the Versor */ |
| 81 |
|
typedef Matrix<T,3,3> MatrixType; |
| 82 |
|
|
| 83 |
|
/** Get a vnl_quaternion with a copy of the internal memory block. */ |
| 84 |
|
vnl_quaternion<T> GetVnlQuaternion( void ) const; |
| 85 |
|
|
| 86 |
|
/** Set the Versor from a Quaternion |
| 87 |
IND |
***\warning After assignment, the corresponding quaternion will |
| 88 |
IND |
************be normalized in order to get a consistent Versor. */ |
| 89 |
|
void Set( const VnlQuaternionType & ); |
| 90 |
|
|
| 91 |
|
/** Set the Versor from Quaternion components. |
| 92 |
IND |
***\warning After assignment, the corresponding quaternion will |
| 93 |
IND |
************be normalized in order to get a consistent Versor. */ |
| 94 |
|
void Set( T x, T y, T z, T w ); |
| 95 |
|
|
| 96 |
|
|
| 97 |
|
/** Default constructor creates a null versor |
| 98 |
|
* (representing 0 degrees rotation). */ |
| 99 |
|
Versor(); |
| 100 |
|
|
| 101 |
|
/** Copy constructor. */ |
| 102 |
|
Versor(const Self & v); |
| 103 |
|
|
| 104 |
|
/** Assignment operator =. Copy the versor argument. */ |
| 105 |
|
const Self& operator=(const Self & v); |
| 106 |
|
|
| 107 |
|
/** Composition operator *=. Compose the current versor |
| 108 |
|
* with the operand and store the result in the current |
| 109 |
|
* versor. */ |
| 110 |
|
const Self& operator*=(const Self & v); |
| 111 |
|
|
| 112 |
|
/** Division operator /=. Divide the current versor |
| 113 |
|
* with the operand and store the result in the current |
| 114 |
|
* versor. This is equivalent to compose the Versor with |
| 115 |
|
* the reciprocal of the operand \sa GetReciprocal */ |
| 116 |
|
const Self& operator/=(const Self & v); |
| 117 |
|
|
| 118 |
|
|
| 119 |
|
/** Get Tensor part of the Versor. |
| 120 |
|
* Given that Versors are normalized quaternions this value |
| 121 |
|
* is expected to be 1.0 always */ |
| 122 |
|
ValueType GetTensor(void) const; |
| 123 |
|
|
| 124 |
|
/** Normalize the Versor. |
| 125 |
|
* Given that Versors are normalized quaternions this method |
| 126 |
|
* is provided only for convinience when it is suspected that |
| 127 |
|
* a versor could be out of the unit sphere. */ |
| 128 |
|
void Normalize(void); |
| 129 |
|
|
| 130 |
|
/** Get Conjugate versor. Returns the versor that produce |
| 131 |
|
* a rotation by the same angle but in opposite direction. */ |
| 132 |
|
Self GetConjugate(void) const; |
| 133 |
|
|
| 134 |
|
/** Get Reciprocal versor. Returns the versor that composed |
| 135 |
|
* with this one will result in a scalar operator equals to 1. |
| 136 |
|
* It is also equivalent to 1/this. */ |
| 137 |
|
Self GetReciprocal(void) const; |
| 138 |
|
|
| 139 |
|
/** Versor operator*. Performs the composition of two versors. |
| 140 |
|
* this operation is NOT commutative. */ |
| 141 |
|
Self operator*(const Self &vec) const; |
| 142 |
|
|
| 143 |
|
/** Versor operator/. Performs the division of two versors. */ |
| 144 |
|
Self operator/(const Self &vec) const; |
| 145 |
|
|
| 146 |
|
/** Versor operator== Performs the comparison between two versors. |
| 147 |
|
* this operation uses an arbitrary threshold for the comparison. */ |
| 148 |
|
bool operator==(const Self &vec) const; |
| 149 |
|
|
| 150 |
|
/** Versor operator!= Performs the comparison between two versors. |
| 151 |
|
* this operation uses an arbitrary threshold for the comparison. */ |
| 152 |
|
bool operator!=(const Self &vec) const; |
| 153 |
|
|
| 154 |
|
/** Returns the Scalar part. */ |
| 155 |
|
ValueType GetScalar( void ) const; |
| 156 |
|
|
| 157 |
|
/** Returns the X component. */ |
| 158 |
|
ValueType GetX( void ) const |
| 159 |
|
{ return m_X; } |
| 160 |
|
|
| 161 |
|
/** Returns the Y component. */ |
| 162 |
|
ValueType GetY( void ) const |
| 163 |
|
{ return m_Y; } |
| 164 |
|
|
| 165 |
|
/** Returns the Z component. */ |
| 166 |
|
ValueType GetZ( void ) const |
| 167 |
|
{ return m_Z; } |
| 168 |
|
|
| 169 |
|
/** Returns the W component. */ |
| 170 |
|
ValueType GetW( void ) const |
| 171 |
|
{ return m_W; } |
| 172 |
|
|
| 173 |
|
/** Returns the rotation angle in radians. */ |
| 174 |
|
ValueType GetAngle( void ) const; |
| 175 |
|
|
| 176 |
|
/** Returns the axis of the rotation. |
| 177 |
|
* It is a unit vector parallel to the axis. */ |
| 178 |
IND |
***VectorType GetAxis( void ) const; |
| 179 |
|
|
| 180 |
|
/** Returns the Right part |
| 181 |
|
* It is a vector part of the Versor. It is |
| 182 |
|
* called Right because it is equivalent to |
| 183 |
|
* a right angle rotation. */ |
| 184 |
IND |
***VectorType GetRight( void ) const; |
| 185 |
|
|
| 186 |
|
/** Set the versor using a vector and angle |
| 187 |
|
* the unit vector parallel to the given vector |
| 188 |
|
* will be used. The angle is expected in radians. */ |
| 189 |
|
void Set( const VectorType & axis, ValueType angle ); |
| 190 |
|
|
| 191 |
|
/** Set the versor using an orthogonal matrix. |
| 192 |
|
* Based on code from: |
| 193 |
LEN |
* http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm |
| 194 |
|
*/ |
| 195 |
|
void Set( const MatrixType & m ); |
| 196 |
|
|
| 197 |
|
/** Set the versor using the right part. |
| 198 |
|
* the magnitude of the vector given is assumed to |
| 199 |
|
* be equal to sin(angle/2). |
| 200 |
|
* This method will compute internally the scalar |
| 201 |
|
* part that preserve the Versor as a unit quaternion. */ |
| 202 |
|
void Set( const VectorType & axis ); |
| 203 |
|
|
| 204 |
|
/** Sets a rotation around the X axis using the parameter |
| 205 |
|
* as angle in radians. This is a method provided for |
| 206 |
|
* convinience to initialize a rotation. The effect of |
| 207 |
|
* this methods is not cumulative with any value previously |
| 208 |
|
* stored in the Versor. |
| 209 |
|
* \sa Set \sa SetRotationAroundY \sa SetRotationAroundZ */ |
| 210 |
|
void SetRotationAroundX( ValueType angle ); |
| 211 |
|
|
| 212 |
|
/** Sets a rotation around the Y axis using the parameter |
| 213 |
|
* as angle in radians. This is a method provided for |
| 214 |
|
* convinience to initialize a rotation. The effect of |
| 215 |
|
* this methods is not cumulative with any value previously |
| 216 |
|
* stored in the Versor. |
| 217 |
|
* \sa Set \sa SetRotationAroundX \sa SetRotationAroundZ */ |
| 218 |
|
void SetRotationAroundY( ValueType angle ); |
| 219 |
|
|
| 220 |
|
/** Sets a rotation around the Y axis using the parameter |
| 221 |
|
* as angle in radians. This is a method provided for |
| 222 |
|
* convinience to initialize a rotation. The effect of |
| 223 |
|
* this methods is not cumulative with any value previously |
| 224 |
|
* stored in the Versor. |
| 225 |
|
* \sa Set \sa SetRotationAroundX \sa SetRotationAroundY */ |
| 226 |
|
void SetRotationAroundZ( ValueType angle ); |
| 227 |
|
|
| 228 |
|
/** Reset the values so the versor is equivalent to an identity |
| 229 |
|
* transformation. This is equivalent to set a zero angle */ |
| 230 |
|
void SetIdentity(); |
| 231 |
|
|
| 232 |
|
/** Transform a vector. */ |
| 233 |
|
VectorType Transform( const VectorType & v ) const; |
| 234 |
|
|
| 235 |
|
/** Transform a covariant vector. */ |
| 236 |
|
CovariantVectorType Transform( const CovariantVectorType & v ) const; |
| 237 |
|
|
| 238 |
|
/** Transform a point. */ |
| 239 |
|
PointType Transform( const PointType & v ) const; |
| 240 |
|
|
| 241 |
|
/** Transform a vnl_vector. */ |
| 242 |
|
VnlVectorType Transform( const VnlVectorType & v ) const; |
| 243 |
|
|
| 244 |
|
/** Get the matrix representation. */ |
| 245 |
|
MatrixType GetMatrix(void) const; |
| 246 |
|
|
| 247 |
|
/** Get the Square root of the unit quaternion. */ |
| 248 |
|
Self SquareRoot(void) const; |
| 249 |
|
|
| 250 |
|
/** Compute the Exponential of the unit quaternion |
| 251 |
|
* Exponentiation by a factor is equivalent to |
| 252 |
|
* multiplication of the rotaion angle of the quaternion. */ |
| 253 |
|
Self Exponential( ValueType exponent ) const; |
| 254 |
|
|
| 255 |
|
private: |
| 256 |
IND |
***/** Component parallel to x axis. */ |
| 257 |
IND |
***ValueType m_X; |
| 258 |
|
|
| 259 |
IND |
***/** Component parallel to y axis. */ |
| 260 |
IND |
***ValueType m_Y; |
| 261 |
|
|
| 262 |
IND |
***/** Component parallel to z axis. */ |
| 263 |
IND |
***ValueType m_Z; |
| 264 |
|
|
| 265 |
IND |
***/** Escalar component of the Versor. */ |
| 266 |
IND |
***ValueType m_W; |
| 267 |
|
}; |
| 268 |
|
|
| 269 |
|
template< class T> |
| 270 |
|
ITK_EXPORT std::ostream& operator<<( std::ostream& os, |
| 271 |
|
const Versor<T> & v) |
| 272 |
|
{ |
| 273 |
|
os << "[ "; |
| 274 |
|
os << v.GetX() << ", " << v.GetY() << ", "; |
| 275 |
|
os << v.GetZ() << ", " << v.GetW() << " ]"; |
| 276 |
|
return os; |
| 277 |
|
} |
| 278 |
|
|
| 279 |
|
template< class T> |
| 280 |
|
ITK_EXPORT std::istream& operator>>(std::istream& is, |
| 281 |
|
Versor<T> & v); |
| 282 |
|
|
| 283 |
|
|
| 284 |
|
} // end namespace itk |
| 285 |
|
|
| 286 |
|
|
| 287 |
|
#ifndef ITK_MANUAL_INSTANTIATION |
| 288 |
|
#include "itkVersor.txx" |
| 289 |
|
#endif |
| 290 |
|
|
| 291 |
|
|
| 292 |
|
#endif |
| 293 |
|
|