Simbody

UnitVec.h

Go to the documentation of this file.
00001 #ifndef SimTK_UNITVEC_H 
00002 #define SimTK_UNITVEC_H 
00003 
00004 /* -------------------------------------------------------------------------- *
00005  *                      SimTK Core: SimTK Simmatrix(tm)                       *
00006  * -------------------------------------------------------------------------- *
00007  * This is part of the SimTK Core 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.               *
00011  *                                                                            *
00012  * Portions copyright (c) 2005-10 Stanford University and the Authors.        *
00013  * Authors: Michael Sherman                                                   *
00014  * Contributors: Paul Mitiguy                                                 *
00015  *                                                                            *
00016  * Permission is hereby granted, free of charge, to any person obtaining a    *
00017  * copy of this software and associated documentation files (the "Software"), *
00018  * to deal in the Software without restriction, including without limitation  *
00019  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00020  * and/or sell copies of the Software, and to permit persons to whom the      *
00021  * Software is furnished to do so, subject to the following conditions:       *
00022  *                                                                            *
00023  * The above copyright notice and this permission notice shall be included in *
00024  * all copies or substantial portions of the Software.                        *
00025  *                                                                            *
00026  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00027  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00028  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00029  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00030  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00031  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00032  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00033  * -------------------------------------------------------------------------- */
00034 
00038 #include "SimTKcommon/SmallMatrix.h"
00039 #include "SimTKcommon/internal/CoordinateAxis.h"
00040 
00041 #include <iosfwd>  // Forward declaration of iostream
00042 
00043 namespace SimTK {
00044 
00045 //-----------------------------------------------------------------------------
00046 // Forward declarations. These are templatized by precision P and and stride S
00047 // but always have length 3. TODO: this should be generalized to other lengths.
00048 template <class P, int S> class UnitVec;
00049 template <class P, int S> class UnitRow;
00050 
00051 // UnitVec3 is more intelligible name for UnitVec<Real,1>.
00052 typedef UnitVec<Real,1>     UnitVec3;
00053 typedef UnitVec<float,1>    fUnitVec3;
00054 typedef UnitVec<double,1>   dUnitVec3;
00055 
00056 //-----------------------------------------------------------------------------
00062 //-----------------------------------------------------------------------------
00063 template <class P, int S>
00064 class UnitVec : public Vec<3,P,S> {
00065     typedef P   RealP;
00066 public:
00067     typedef Vec<3,P,S>      BaseVec;
00068     typedef UnitRow<P,S>    TransposeType;
00069 
00072     UnitVec() : BaseVec(NTraits<P>::getNaN()) {}
00073 
00076     UnitVec(const UnitVec& u) 
00077     :   BaseVec( static_cast<const BaseVec&>(u) ) {}
00078 
00081     template <int S2> UnitVec(const UnitVec<P,S2>& u) 
00082     :   BaseVec( static_cast<const typename UnitVec<P,S2>::BaseVec&>(u) ) {}
00083 
00085     explicit UnitVec(const BaseVec& v) : BaseVec(v/v.norm()) {}
00088     template <int S2> 
00089     explicit UnitVec(const Vec<3,P,S2>& v) : BaseVec(v/v.norm())  {}
00090 
00094     UnitVec(const RealP& x, const RealP& y, const RealP& z) : BaseVec(x,y,z)  
00095     {   static_cast<BaseVec&>(*this) /= BaseVec::norm(); }
00096 
00099     UnitVec(const CoordinateAxis& axis) : BaseVec(0) 
00100     {   BaseVec::operator[](axis) = 1; }
00101 
00105     UnitVec(const CoordinateDirection& dir) : BaseVec(0) 
00106     {   BaseVec::operator[](dir.getAxis()) = RealP(dir.getDirection()); }
00107 
00110     explicit UnitVec(int axis) : BaseVec(0) 
00111     {   assert(0 <= axis && axis <= 2);
00112         BaseVec::operator[](axis) = 1; }
00113 
00115     UnitVec& operator=(const UnitVec& u) 
00116     {   BaseVec::operator=(static_cast<const BaseVec&>(u)); 
00117         return *this; }
00118 
00121     template <int S2> UnitVec& operator=(const UnitVec<P,S2>& u) 
00122     {   BaseVec::operator=(static_cast<const typename UnitVec<P,S2>::BaseVec&>(u));
00123         return *this; }
00124 
00126     const BaseVec& asVec3() const {return static_cast<const BaseVec&>(*this);}
00127 
00128     // Override Vec3 methods which preserve length. These return a 
00129     // packed UnitVec regardless of our stride.
00130 
00133     UnitVec<P,1> negate()    const {return UnitVec<P,1>(-asVec3(),true);}
00136     UnitVec<P,1> operator-() const {return negate();}
00137 
00140     const TransposeType& operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
00143     TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
00144 
00145     // We have to define these here so that the non-const ones won't be
00146     // inherited. We don't trust anyone to write on one element of a UnitVec!
00147 
00151     const RealP&  operator[](int i) const  { return BaseVec::operator[](i); }
00155     const RealP&  operator()(int i) const  { return BaseVec::operator()(i); }
00156 
00162     UnitVec<P,1> abs() const {return UnitVec<P,1>( asVec3().abs(), true );}
00163 
00167     inline UnitVec<P,1> perp() const;
00168 
00172     UnitVec(const BaseVec& v, bool) : BaseVec(v) {}
00177     template <int S2> UnitVec(const Vec<3,RealP,S2>& v, bool) : BaseVec(v) { }
00178 };
00179 
00180 
00181 template <class P, int S> inline UnitVec<P,1> 
00182 UnitVec<P,S>::perp() const {
00183     // Choose the coordinate axis which makes the largest angle
00184     // with this vector, that is, has the "least u" along it.
00185     const UnitVec<P,1> u(abs());    // reflect to first octant
00186     const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
00187                                      : (u[1] <= u[2] ? 1 : 2);
00188     // Cross returns a Vec3 result which is then normalized.
00189     return UnitVec<P,1>( *this % UnitVec<P,1>(minAxis) );
00190 }
00191 
00194 template <class P, int S1, int S2> inline bool
00195 operator==(const UnitVec<P,S1>& u1, const UnitVec<P,S2>& u2)
00196 {   return u1.asVec3() == u2.asVec3(); }
00197 
00201 template <class P, int S1, int S2> inline bool
00202 operator!=(const UnitVec<P,S1>& u1, const UnitVec<P,S2>& u2)
00203 {   return !(u1==u2); }
00204 
00205 //-----------------------------------------------------------------------------
00210 //-----------------------------------------------------------------------------
00211 template <class P, int S>
00212 class UnitRow : public Row<3,P,S> {
00213     typedef P   RealP;
00214 public:
00215     typedef Row<3,P,S>      BaseRow;
00216     typedef UnitVec<P,S>    TransposeType;
00217 
00218     UnitRow() : BaseRow(NTraits<P>::getNaN()) { }
00219 
00221     UnitRow(const UnitRow& u) 
00222     :   BaseRow(static_cast<const BaseRow&>(u)) {}
00223 
00226     template <int S2> UnitRow(const UnitRow<P,S2>& u)
00227     :   BaseRow(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u)) { }
00228 
00230     UnitRow& operator=(const UnitRow& u) 
00231     {   BaseRow::operator=(static_cast<const BaseRow&>(u)); 
00232         return *this; }
00233 
00235     template <int S2> UnitRow& operator=(const UnitRow<P,S2>& u) 
00236     {   BaseRow::operator=(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u));
00237         return *this; }
00238 
00240     explicit UnitRow(const BaseRow& v) : BaseRow(v/v.norm()) {}
00243     template <int S2> 
00244     explicit UnitRow(const Row<3,P,S2>& v) : BaseRow(v/v.norm()) {}
00245 
00248     UnitRow(const RealP& x, const RealP& y, const RealP& z)
00249     :   BaseRow(x,y,z)
00250     {   static_cast<BaseRow&>(*this) /= BaseRow::norm(); }
00251 
00253     explicit UnitRow(int axis) : BaseRow(0) 
00254     {   assert(0 <= axis && axis <= 2);
00255         BaseRow::operator[](axis) = 1; }
00256 
00258     const BaseRow& asRow3() const  {return static_cast<const BaseRow&>(*this);}
00259 
00260     // Override Row3 methods which preserve length. These return the 
00261     // packed UnitRow regardless of our stride.
00262 
00265     UnitRow<P,1> negate()    const  { return UnitRow<P,1>(-asRow3(),true); }
00268     UnitRow<P,1> operator-() const  { return negate();}
00269 
00272     const TransposeType&  operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
00275     TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
00276 
00277     // We have to define these here so that the non-const ones won't be
00278     // inherited. We don't trust anyone to write on one element of a UnitRow!
00279 
00283     const RealP&  operator[](int i) const  { return BaseRow::operator[](i); }
00287     const RealP&  operator()(int i) const  { return BaseRow::operator()(i); }
00288 
00294     UnitRow<P,1> abs() const {return UnitRow<P,1>(asRow3().abs(),true);}
00295 
00299     inline UnitRow<P,1> perp() const;
00300 
00301     // This constructor is only for our friends whom we trust to
00302     // give us an already-normalized vector.
00303     UnitRow( const BaseRow& v, bool ) : BaseRow(v) { }
00304     template <int S2> UnitRow( const Row<3,P,S2>& v, bool ) : BaseRow(v) { }
00305 };
00306 
00307 template <class P, int S>
00308 inline UnitRow<P,1> UnitRow<P,S>::perp() const {
00309     // Choose the coordinate axis which makes the largest angle
00310     // with this vector, that is, has the "least u" along it.
00311     const UnitRow<P,1> u(abs());    // reflect to first octant
00312     const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
00313                                      : (u[1] <= u[2] ? 1 : 2);
00314     // Cross returns a Row3 result which is then normalized.
00315     return UnitRow<P,1>(*this % UnitRow<P,1>(minAxis));
00316 }
00317 
00318 
00321 template <class P, int S1, int S2> inline bool
00322 operator==(const UnitRow<P,S1>& u1, const UnitRow<P,S2>& u2)
00323 {   return u1.asRow3() == u2.asRow3(); }
00324 
00328 template <class P, int S1, int S2> inline bool
00329 operator!=(const UnitRow<P,S1>& u1, const UnitRow<P,S2>& u2)
00330 {   return !(u1==u2); }
00331 
00332 //------------------------------------------------------------------------------
00333 }  // End of namespace SimTK
00334 
00335 //--------------------------------------------------------------------------
00336 #endif // SimTK_UNITVEC_H_
00337 //--------------------------------------------------------------------------
00338 
00339 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines