00001 //----------------------------------------------------------------------------- 00002 // File: Quaternion.h 00003 // Class: Quaternion 00004 // Parent: Vec4 00005 // Purpose: Quaternion (Euler parameters) for representing orientation 00006 //----------------------------------------------------------------------------- 00007 #ifndef SimTK_QUATERNION_H 00008 #define SimTK_QUATERNION_H 00009 00010 /* -------------------------------------------------------------------------- * 00011 * SimTK Core: SimTK Simmatrix(tm) * 00012 * -------------------------------------------------------------------------- * 00013 * This is part of the SimTK Core biosimulation toolkit originating from * 00014 * Simbios, the NIH National Center for Physics-Based Simulation of * 00015 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00016 * Medical Research, grant U54 GM072970. See https://simtk.org. * 00017 * * 00018 * Portions copyright (c) 2005-7 Stanford University and the Authors. * 00019 * Authors: Michael Sherman and Paul Mitiguy * 00020 * * 00021 * Permission is hereby granted, free of charge, to any person obtaining a * 00022 * copy of this software and associated documentation files (the "Software"), * 00023 * to deal in the Software without restriction, including without limitation * 00024 * the rights to use, copy, modify, merge, publish, distribute, sublicense, * 00025 * and/or sell copies of the Software, and to permit persons to whom the * 00026 * Software is furnished to do so, subject to the following conditions: * 00027 * * 00028 * The above copyright notice and this permission notice shall be included in * 00029 * all copies or substantial portions of the Software. * 00030 * * 00031 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * 00032 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * 00033 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * 00034 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 00035 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 00036 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * 00037 * USE OR OTHER DEALINGS IN THE SOFTWARE. * 00038 * -------------------------------------------------------------------------- */ 00039 00040 //----------------------------------------------------------------------------- 00041 #include "SimTKcommon/SmallMatrix.h" 00042 #include "SimTKcommon/internal/UnitVec.h" 00043 //----------------------------------------------------------------------------- 00044 #include <iosfwd> // Forward declaration of iostream 00045 //----------------------------------------------------------------------------- 00046 00047 00048 //----------------------------------------------------------------------------- 00049 namespace SimTK { 00050 00051 //----------------------------------------------------------------------------- 00052 // Forward declarations 00053 class Rotation; 00054 00055 00056 //----------------------------------------------------------------------------- 00071 //----------------------------------------------------------------------------- 00072 class Quaternion : public Vec4 { 00073 public: 00075 Quaternion() : Vec4(1,0,0,0) { } 00076 00078 Quaternion( const Quaternion& q ) : Vec4(q) {} 00079 00081 Quaternion& operator=( const Quaternion& q ) { Vec4::operator=( q.asVec4() ); return *this; } 00082 00084 Quaternion( Real e0, Real e1, Real e2, Real e3 ) : Vec4(e0,e1,e2,e3) { normalizeThis(); } 00085 explicit Quaternion( const Vec4& q ) : Vec4(q) { normalizeThis(); } 00086 00088 SimTK_SimTKCOMMON_EXPORT explicit Quaternion( const Rotation& ); 00089 00092 void setQuaternionToZeroRotation() { Vec4::operator=( Vec4(1,0,0,0) ); } 00093 void setQuaternionToNaN() { Vec4::setToNaN(); } 00094 00097 SimTK_SimTKCOMMON_EXPORT void setQuaternionFromAngleAxis( const Vec4& av ); 00098 SimTK_SimTKCOMMON_EXPORT void setQuaternionFromAngleAxis( const Real& a, const UnitVec3& v ); 00099 00101 SimTK_SimTKCOMMON_EXPORT Vec4 convertQuaternionToAngleAxis() const; 00102 00104 const Vec4& asVec4() const { return *static_cast<const Vec4*>(this); } 00105 00111 Quaternion& normalizeThis() { 00112 const Real epsilon = std::numeric_limits<Real>::epsilon(); 00113 const Real magnitude = Vec4::norm(); 00114 if( magnitude == 0 ) setQuaternionToZeroRotation(); 00115 else if( magnitude < epsilon ) setQuaternionToNaN(); 00116 else (*this) *= (1.0/magnitude); 00117 return *this; 00118 } 00119 00124 Quaternion( const Vec4& v, bool ) : Vec4(v) {} 00125 00126 //---------------------------------------------------------------------------------------------------- 00127 // The following code is obsolete - it is here temporarily for backward compatibility (Mitiguy 10/13/2007) 00128 //---------------------------------------------------------------------------------------------------- 00129 private: 00130 Vec4 convertToAngleAxis() const { return convertQuaternionToAngleAxis(); } 00131 void setToAngleAxis( const Vec4& av ) { setQuaternionFromAngleAxis(av); } 00132 void setToAngleAxis( const Real& a, const UnitVec3& v ) { setQuaternionFromAngleAxis(a,v); } 00133 void setToNaN() { setQuaternionToNaN(); } 00134 void setToZero() { setQuaternionToZeroRotation(); } 00135 00136 }; 00137 00138 00139 //------------------------------------------------------------------------------ 00140 } // End of namespace SimTK 00141 00142 //-------------------------------------------------------------------------- 00143 #endif // SimTK_QUATERNION_H_ 00144 //-------------------------------------------------------------------------- 00145