📄 vnl_quaternion.h
字号:
// This is core/vnl/vnl_quaternion.h
#ifndef vnl_quaternion_h_
#define vnl_quaternion_h_
#ifdef VCL_NEEDS_PRAGMA_INTERFACE
#pragma interface
#endif
//:
// \file
// \brief Unit quaternion represents rotation in 3D.
// \author awf@robots.ox.ac.uk
// \date 16 Mar 00
//
// \verbatim
// Modifications
// 20-05-2000 fsm. changed FLOAT to T since gcc will barf at
// the very reasonable forward declaration
// template <class FLOAT> class vnl_quaternion;
// 23-3-2001 LSB (Manchester) Tidied documentation
// 13-1-2003 Peter Vanroose - removed unimplemented method rotation_matrix()
// 20-2-2006 Ian Scott - Added conversion to from Euler angles
// 06-5-2006 Peter Vanroose - replaced all vnl_vector by vnl_vector_fixed
// \endverbatim
#include <vnl/vnl_vector_fixed.h>
#include <vnl/vnl_matrix_fixed.h>
#include <vcl_iostream.h>
//: 4-element vector that represents rotation in 3D.
// vnl_quaternion is a 4-element vector with 1 real and 3 imaginary
// components:
// \code
// q = r + (i*x + j*y + k*z)
// r = cos(theta/2)
// (x, y, z) = sin(theta/2) (kx, ky, kz)
// \endcode
// where theta and k are respectively the angle and axis of rotation.
// 3D vectors can be thought of as imaginary quaternions, and so a
// quaternion is represented as a vnl_vector_fixed<T,4> with the imaginary
// part before the real part for 1-1 alignment.
//
// Unit quaternions provide a more efficient representation for
// rotation, than the usual orthonormal matrix that has nine
// parameters and six orthonormal constraints. The unit
// quaternion has only one unit magnitude constraint. Composing
// rotations with quaternions results in fewer multiplications
// and less error. To insure valid rotation results, the
// nearest unit quaternion is computed, and this is much easier
// than finding the nearest orthonormal matrix. Transforming
// vectors with a quaternion requires more operations compared
// to multiplication with the equivalent orthonormal matrix.
//
// \sa
// vnl_vector_fixed and vnl_matrix_fixed for basic operations on vectors and matrices.
// \sa
// Envelope for envelope-letter scheme that avoids deep copy on
// return by value in arithmetic expressions like: q1 * q2 * q3 *...
//
export template <class T>
class vnl_quaternion : public vnl_vector_fixed<T, 4>
{
typedef vnl_vector_fixed<T,4> Base;
public:
//: Constructor for null quaternion
vnl_quaternion() {}
//: Construct quaternion from components x,y,z,r
vnl_quaternion(T x, T y, T z, T r);
//: Construct quaternion from Euler Angles,
// That is a rotation about the X axis, followed by Y, followed by
// the Z axis, using a fixed reference frame.
vnl_quaternion(T theta_X, T theta_Y, T theta_Z);
//: Construct quaternion from axis and angle of rotation.
// \note If you specify an angle in [0, 2pi], then methods angle() and axis() will return the same values.
// However, if you specify an angle in [-2pi, 0], then methods angle() and axis() will return values with opposite signs.
// \sa vnl_quaternion::angle()
// \sa vnl_quaternion::axis()
vnl_quaternion(vnl_vector_fixed<T,3> const& axis, T angle);
//: Construct quaternion from from 3x3 row-major matrix
explicit vnl_quaternion(vnl_matrix_fixed<T,3,3> const& transform);
//: Construct quaternion from a 3D vector
vnl_quaternion(vnl_vector_fixed<T,3> const& vec);
//: Construct quaternion from a 4D vector
vnl_quaternion (vnl_vector_fixed<T,4> const& vec);
//: Copy constructor -- Creates a copy of from quaternion.
inline vnl_quaternion(vnl_quaternion<T> const& from) : Base(from) {}
//: Free internal array
inline ~vnl_quaternion() {} // vnl_vector_fixed will free data array
//: Overloads assignment operator to copy rhs quaternion into lhs quaternion.
inline vnl_quaternion& operator= (vnl_quaternion<T> const& rhs) { Base::operator=(rhs); return *this; }
//: Imaginary component, parallel to axis of rotation.
// Use this accessor to both get and set the component.
inline T& x() { return this->operator()(0); }
//: Imaginary component, parallel to axis of rotation.
// Use this accessor to both get and set the component.
inline T& y() { return this->operator()(1); }
//: Imaginary component, parallel to axis of rotation.
// Use this accessor to both get and set the component.
inline T& z() { return this->operator()(2); }
//: Real component.
// Use this accessor to both get and set the component.
inline T& r() { return this->operator()(3); }
//: Imaginary component, parallel to axis of rotation.
// Use this accessor to get the component.
inline T x() const { return this->operator()(0); }
//: Imaginary component, parallel to axis of rotation.
// Use this accessor to get the component.
inline T y() const { return this->operator()(1); }
//: Imaginary component, parallel to axis of rotation.
// Use this accessor to get the component.
inline T z() const { return this->operator()(2); }
//: Real component.
// Use this accessor to get the component.
inline T r() const { return this->operator()(3); }
//: Copies and returns the real part.
inline T real() const { return (*this)[3]; }
//: Copies and returns the imaginary part.
inline vnl_vector_fixed<T,3> imaginary() const { return this->extract(3,0); }
//: Axis of rotation.
// \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).
vnl_vector_fixed<T,3> axis() const;
//: Angle of rotation.
// \note Returned angle lies in [0, 2*pi]
T angle() const;
//: 3x3 rotation matrix
vnl_matrix_fixed<T,3,3> rotation_matrix_transpose() const;
//: 4x4 rotation matrix
vnl_matrix_fixed<T,4,4> rotation_matrix_transpose_4() const;
//: Same real, opposite img part
vnl_quaternion<T> conjugate() const;
//: Inverse for nonzero quat
vnl_quaternion<T> inverse() const;
vnl_quaternion<T> operator* (vnl_quaternion<T> const&) const;
//: Rotate 3D v
// The quaternion must be normalised first.
vnl_vector_fixed<T,3> rotate(vnl_vector_fixed<T,3> const&) const;
//: Rotation representation in Euler angles.
// The angles raturned will be [theta_X,theta_Y,theta_Z]
// where the final rotation is found be first applying theta_X radians
// about the X axis, then theta_Y about the Y-axis, etc.
// The axes stay in a fixed reference frame.
// The quaternion mut be normalised first.
vnl_vector_fixed<T,3> rotation_euler_angles() const;
};
//: operator<<
// \relates vnl_quaternion
template <class T>
inline vcl_ostream& operator<< (vcl_ostream& os, vnl_quaternion<T> const& q)
{
return os << *((const vnl_vector_fixed<T,4>*) &q);
}
#define VNL_QUATERNION_INSTANTIATE(T) extern "Please #include <vnl/vnl_quaternion.txx> first"
#endif // vnl_quaternion_h_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -