/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */ /* $Id: vctQuaternionBase.h,v 1.10 2007/04/26 19:33:58 anton Exp $ Author(s): Anton Deguet Created on: 2005-08-18 (C) Copyright 2005-2007 Johns Hopkins University (JHU), All Rights Reserved. --- begin cisst license - do not edit --- This software is provided "as is" under an open source license, with no warranty. The complete license can be found in license.txt and http://www.cisst.org/cisst/license.txt. --- end cisst license --- */ /*! \file \brief Declaration of vctQuaternionBase */ #ifndef _vctQuaternionBase_h #define _vctQuaternionBase_h #include #include #include // always the last file to include #include /*! \brief Define a quaternion container. It is important to note that the class vctQuaternion is for any quaternion, i.e. it does not necessary represent a unit quaternion. \param _baseType The base class used to contain the 4 elements. \sa vctFixedSizeVector, vctDynamicVector */ template class vctQuaternionBase: public _containerType { protected: /*! Allocate memory for the underlying container if needed. By default, this methods does nothing. For any container requiring a memory allocation, it is necessary to specialize this method. */ inline void Allocate(void) {} public: enum {SIZE = 4}; typedef _containerType BaseType; typedef _containerType ContainerType; typedef vctQuaternionBase<_containerType> ThisType; /* no need to document, inherit doxygen documentation from base class */ VCT_CONTAINER_TRAITS_TYPEDEFS(typename ContainerType::value_type); typedef cmnTypeTraits TypeTraits; /*! Default constructor. Does nothing. */ inline vctQuaternionBase(void) { this->Allocate(); } /*! Constructor from 4 elements. \param x The first imaginary component \param y The second imaginary component \param z The third imaginary component \param r The real component */ inline vctQuaternionBase(const value_type & x, const value_type & y, const value_type & z, const value_type & r) { this->Allocate(); this->X() = x; this->Y() = y; this->Z() = z; this->R() = r; } /* Methods X, Y, Z are inherited, add methods R() */ /*! Returns the last element of the quaternion, i.e. the real part. This method is const. The methods X(), Y() and Z() are inherited from the base class. */ const_reference R(void) const { return *(this->Pointer(3)); } /*! Access the last element of the quaternion, i.e. the real part. This method is not const. The methods X(), Y() and Z() are inherited from the base class. */ reference R(void) { return *(this->Pointer(3)); } /*! Sets this quaternion as the conjugate of another one. \param otherQuaternion Quaternion used to compute the conjugate. */ inline ThisType & ConjugateOf(const ThisType & otherQuaternion) { this->X() = - otherQuaternion.X(); this->Y() = - otherQuaternion.Y(); this->Z() = - otherQuaternion.Z(); this->R() = otherQuaternion.R(); return *this; } /*! Replaces this quaternion by its conjugate. */ inline ThisType & ConjugateSelf(void) { this->X() = - this->X(); this->Y() = - this->Y(); this->Z() = - this->Z(); return *this; } /*! Returns the conjugate of this quaternion. This method returns a copy of the conjugate and does not modify this quaternion. */ inline ThisType Conjugate(void) const { ThisType result; result.ConjugateOf(*this); return result; } /*! Set this quaternion as the product of two other ones. \param quat1 Left operand \param quat2 Right operand \note Quaternion product in non-commutative. */ inline ThisType & ProductOf(const ThisType & quat1, const ThisType & quat2) { this->X() = quat1.R() * quat2.X() + quat1.X() * quat2.R() + quat1.Y() * quat2.Z() - quat1.Z() * quat2.Y(); this->Y() = quat1.R() * quat2.Y() - quat1.X() * quat2.Z() + quat1.Y() * quat2.R() + quat1.Z() * quat2.X(); this->Z() = quat1.R() * quat2.Z() + quat1.X() * quat2.Y() - quat1.Y() * quat2.X() + quat1.Z() * quat2.R(); this->R() = quat1.R() * quat2.R() - quat1.X() * quat2.X() - quat1.Y() * quat2.Y() - quat1.Z() * quat2.Z(); return *this; } /*! Compute the quotient quat1 / quat2. The reciprocal of a quaternion q is conj(q) / norm(q) */ inline ThisType & QuotientOf(const ThisType & quat1, const ThisType & quat2) { const value_type quat2Norm = value_type(quat2.Norm()); BaseType quat2I; quat2I.Assign(-quat2.X() / quat2Norm, -quat2.Y() / quat2Norm, -quat2.Z() / quat2Norm, quat2.R() / quat2Norm); this->X() = quat1.R() * quat2I.X() + quat1.X() * quat2.R() + quat1.Y() * quat2I.Z() - quat1.Z() * quat2I.Y(); this->Y() = quat1.R() * quat2I.Y() - quat1.X() * quat2I.Z() + quat1.Y() * quat2.R() + quat1.Z() * quat2I.X(); this->Z() = quat1.R() * quat2I.Z() + quat1.X() * quat2I.Y() - quat1.Y() * quat2I.X() + quat1.Z() * quat2.R(); this->R() = quat1.R() * quat2.R() - quat1.X() * quat2I.X() - quat1.Y() * quat2I.Y() - quat1.Z() * quat2I.Z(); return *this; } /*! Post-multiply this quaternion by another, i.e., this = this * other. \note Quaternion product is non-commutative. */ inline ThisType & PostMultiply(const ThisType & other) { ThisType result; result = ProductOf(*this, other); *this = result; return *this; } /*! Pre-multiply this quaternion by another, i.e., this = other * this. \note Quaternion product is non-commutative. */ inline ThisType & PreMultiply(const ThisType & other) { ThisType result; result = ProductOf(other, *this); *this = result; return *this; } /*! Divide this quaternion by another, i.e., this = this / other. */ inline ThisType & Divide(const ThisType & other) { ThisType result; result.QuotientOf(*this, other); *this = result; return *this; } /*! Divide this quaternion by a scalar: equal to elementwise division. The method re-implements vector elementwise division, which is otherwise shadowed by the Divide(ThisType) method. */ inline ThisType & Divide(const value_type s) { (static_cast(this))->Divide(s); return *this; } }; /* Specialization of Allocate for a dynamic matrix */ template<> inline void vctQuaternionBase >::Allocate(void) { this->SetSize(SIZE); } template<> inline void vctQuaternionBase >::Allocate(void) { this->SetSize(SIZE); } /*! Product of two quaternions. This operator relies on the method vctQuaternion::ProductOf. \param quat1 Left operand \param quat2 Right operand */ template inline vctQuaternionBase<_containerType> operator * (const vctQuaternionBase<_containerType> & quat1, const vctQuaternionBase<_containerType> & quat2) { vctQuaternionBase<_containerType> result; result.ProductOf(quat1, quat2); return result; } /*! Quotient of two quaternions. This operator relies on the method vctQuaternion::QuotientOf. \param quat1 Left operand \param quat2 Right operand */ template inline vctQuaternionBase<_containerType> operator / (const vctQuaternionBase<_containerType> & quat1, const vctQuaternionBase<_containerType> & quat2) { vctQuaternionBase<_containerType> result; result.QuotientOf(quat1, quat2); return result; } #endif // _vctQuaternionBase_h // **************************************************************************** // Change History // **************************************************************************** // // $Log: vctQuaternionBase.h,v $ // Revision 1.10 2007/04/26 19:33:58 anton // All files in libraries: Applied new license text, separate copyright and // updated dates, added standard header where missing. // // Revision 1.9 2007/01/29 03:29:37 anton // cisstVector: Update quaternion and quaternion based rotation to reflect new // class structure (see ticket #263). // // Revision 1.8 2007/01/23 20:59:27 anton // cisstVector: Updated transformations classes so that non const methods // returning a reference on "this" return a non const reference. This follows // ticket #259. // // Revision 1.7 2006/11/20 20:33:20 anton // Licensing: Applied new license to cisstCommon, cisstVector, cisstNumerical, // cisstInteractive, cisstImage and cisstOSAbstraction. // // Revision 1.6 2005/10/12 18:57:08 pkaz // vctQuaternionBase.h: added include of vctExport.h // // Revision 1.5 2005/10/08 20:16:24 anton // vctQuaternionBase: Sepcialized default ctor to perform required memory // allocation if derived from dynamic vector. // // Revision 1.4 2005/10/06 16:56:37 anton // Doxygen: Corrected errors and some warnings detected by Doxygen 1.4.3. // // Revision 1.3 2005/09/28 20:28:50 anton // libs documentation: Corrected Doxygen links. // // Revision 1.2 2005/09/26 15:41:47 anton // cisst: Added modelines for emacs and vi. // // Revision 1.1 2005/09/01 06:18:08 anton // cisstVector transformations: Added a level of abstraction for all classes // derived from fixed size containers (vctQuaternion, vctQuaternionRotation3, // vctMatrixRotation3, vctRodriguezRotation3). These classes are now derived // from vctXyzBase<_containerType>. This will ease the SWIG wrapping. // // // ****************************************************************************