Simbody
3.4 (development)
|
00001 #ifndef SimTK_SimTKCOMMON_QUATERNION_H 00002 #define SimTK_SimTKCOMMON_QUATERNION_H 00003 00004 /* -------------------------------------------------------------------------- * 00005 * Simbody(tm): SimTKcommon * 00006 * -------------------------------------------------------------------------- * 00007 * This is part of the SimTK biosimulation toolkit originating from * 00008 * Simbios, the NIH National Center for Physics-Based Simulation of * 00009 * Biological Structures at Stanford, funded under the NIH Roadmap for * 00010 * Medical Research, grant U54 GM072970. See https://simtk.org/home/simbody. * 00011 * * 00012 * Portions copyright (c) 2005-12 Stanford University and the Authors. * 00013 * Authors: Michael Sherman, Paul Mitiguy * 00014 * Contributors: * 00015 * * 00016 * Licensed under the Apache License, Version 2.0 (the "License"); you may * 00017 * not use this file except in compliance with the License. You may obtain a * 00018 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * 00019 * * 00020 * Unless required by applicable law or agreed to in writing, software * 00021 * distributed under the License is distributed on an "AS IS" BASIS, * 00022 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 00023 * See the License for the specific language governing permissions and * 00024 * limitations under the License. * 00025 * -------------------------------------------------------------------------- */ 00026 00027 //----------------------------------------------------------------------------- 00028 #include "SimTKcommon/SmallMatrix.h" 00029 #include "SimTKcommon/internal/UnitVec.h" 00030 //----------------------------------------------------------------------------- 00031 #include <iosfwd> // Forward declaration of iostream 00032 //----------------------------------------------------------------------------- 00033 00034 00035 //----------------------------------------------------------------------------- 00036 namespace SimTK { 00037 00038 //----------------------------------------------------------------------------- 00039 // Forward declarations 00040 template <class P> class Rotation_; 00041 template <class P> class Quaternion_; 00042 00043 typedef Quaternion_<Real> Quaternion; 00044 typedef Quaternion_<float> fQuaternion; 00045 typedef Quaternion_<double> dQuaternion; 00046 00047 //----------------------------------------------------------------------------- 00063 //----------------------------------------------------------------------------- 00064 template <class P> 00065 class Quaternion_ : public Vec<4,P> { 00066 typedef P RealP; 00067 typedef Vec<3,P> Vec3P; 00068 typedef Vec<4,P> Vec4P; 00069 public: 00072 Quaternion_() : Vec4P(1,0,0,0) { } 00073 00076 Quaternion_(const Quaternion_& q) : Vec4P(q) {} 00077 00080 Quaternion_& operator=( const Quaternion_& q ) 00081 { Vec4P::operator=(q.asVec4()); return *this; } 00082 00085 Quaternion_( RealP e0, RealP e1, RealP e2, RealP e3 ) : Vec4P(e0,e1,e2,e3) 00086 { normalizeThis(); } 00089 explicit Quaternion_( const Vec4P& q ) : Vec4P(q) 00090 { normalizeThis(); } 00091 00094 SimTK_SimTKCOMMON_EXPORT explicit Quaternion_(const Rotation_<P>&); 00095 00098 void setQuaternionToZeroRotation() {Vec4P::operator=( Vec4P(1,0,0,0) );} 00102 void setQuaternionToNaN() {Vec4P::setToNaN();} 00103 00108 SimTK_SimTKCOMMON_EXPORT void setQuaternionFromAngleAxis(const Vec4P& av); 00112 SimTK_SimTKCOMMON_EXPORT void setQuaternionFromAngleAxis(const RealP& a, const UnitVec<P,1>& v); 00113 00116 SimTK_SimTKCOMMON_EXPORT Vec4P convertQuaternionToAngleAxis() const; 00117 00120 const Vec4P& asVec4() const {return *static_cast<const Vec4P*>(this);} 00121 00132 Quaternion_& normalizeThis() { 00133 const RealP epsilon = std::numeric_limits<RealP>::epsilon(); 00134 const RealP magnitude = Vec4P::norm(); 00135 if( magnitude == 0 ) setQuaternionToZeroRotation(); 00136 else if( magnitude < epsilon ) setQuaternionToNaN(); 00137 else (*this) *= (1/magnitude); 00138 return *this; 00139 } 00140 00147 Quaternion_ normalize() const {return Quaternion_(*this).normalizeThis();} 00148 00154 Quaternion_(const Vec4P& v, bool) : Vec4P(v) {} 00155 00156 //---------------------------------------------------------------------------------------------------- 00157 // The following code is obsolete - it is here temporarily for backward compatibility (Mitiguy 10/13/2007) 00158 //---------------------------------------------------------------------------------------------------- 00159 private: 00160 Vec4P convertToAngleAxis() const { return convertQuaternionToAngleAxis();} 00161 void setToAngleAxis(const Vec4P& av) { setQuaternionFromAngleAxis(av);} 00162 void setToAngleAxis(const RealP& a, const UnitVec<P,1>& v){ setQuaternionFromAngleAxis(a,v);} 00163 void setToNaN() { setQuaternionToNaN(); } 00164 void setToZero() { setQuaternionToZeroRotation();} 00165 00166 }; 00167 00168 00169 //------------------------------------------------------------------------------ 00170 } // End of namespace SimTK 00171 00172 //-------------------------------------------------------------------------- 00173 #endif // SimTK_SimTKCOMMON_QUATERNION_H_ 00174 //-------------------------------------------------------------------------- 00175