UnitVec.h

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // File:     UnitVec.h
00003 // Classes:  UnitVec and UnitRow
00004 // Parents:  Vec and Row
00005 // Purpose:  Unit vector class (pure direction - magnitude is always 1.0)
00006 //-----------------------------------------------------------------------------
00007 #ifndef SimTK_UNITVEC_H 
00008 #define SimTK_UNITVEC_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-9 Stanford University and the Authors.         *
00019  * Authors: Michael Sherman                                                   *
00020  * Contributors: Paul Mitiguy                                                 *
00021  *                                                                            *
00022  * Permission is hereby granted, free of charge, to any person obtaining a    *
00023  * copy of this software and associated documentation files (the "Software"), *
00024  * to deal in the Software without restriction, including without limitation  *
00025  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00026  * and/or sell copies of the Software, and to permit persons to whom the      *
00027  * Software is furnished to do so, subject to the following conditions:       *
00028  *                                                                            *
00029  * The above copyright notice and this permission notice shall be included in *
00030  * all copies or substantial portions of the Software.                        *
00031  *                                                                            *
00032  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00033  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00034  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00035  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00036  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00037  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00038  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00039  * -------------------------------------------------------------------------- */
00040 
00041 //-----------------------------------------------------------------------------
00042 #include "SimTKcommon/SmallMatrix.h"
00043 //-----------------------------------------------------------------------------
00044 #include <iosfwd>  // Forward declaration of iostream
00045 //-----------------------------------------------------------------------------
00046 
00047 //-----------------------------------------------------------------------------
00048 namespace SimTK {
00049 
00050 //-----------------------------------------------------------------------------
00051 // Forward declarations. These are templatized by precision P and and stride S
00052 // but always have length 3. TODO: this should be generalized to other lengths.
00053 template <class P, int S> class UnitVec;
00054 template <class P, int S> class UnitRow;
00055 
00056 // UnitVec3 is more intelligible name for UnitVec<Real,1>.
00057 typedef UnitVec<Real,1> UnitVec3;
00058 
00059 
00060 //-----------------------------------------------------------------------------
00066 //-----------------------------------------------------------------------------
00067 template <class P, int S>
00068 class UnitVec : public Vec<3,P,S> {
00069     typedef P   RealP;
00070 public:
00071     typedef Vec<3,P,S>      BaseVec;
00072     typedef UnitRow<P,S>    TransposeType;
00073 
00076     UnitVec() : BaseVec(NTraits<P>::getNaN()) {}
00077 
00080     UnitVec(const UnitVec& u) 
00081     :   BaseVec( static_cast<const BaseVec&>(u) ) {}
00082 
00085     template <int S2> UnitVec(const UnitVec<P,S2>& u) 
00086     :   BaseVec( static_cast<const typename UnitVec<P,S2>::BaseVec&>(u) ) {}
00087 
00089     explicit UnitVec(const BaseVec& v) : BaseVec(v/v.norm()) {}
00092     template <int S2> 
00093     explicit UnitVec(const Vec<3,P,S2>& v) : BaseVec(v/v.norm())  {}
00094 
00098     UnitVec(const RealP& x, const RealP& y, const RealP& z) : BaseVec(x,y,z)  
00099     {   static_cast<BaseVec&>(*this) /= BaseVec::norm(); }
00100 
00102     explicit UnitVec(int axis) : BaseVec(0) 
00103     {   assert(0 <= axis && axis <= 2);
00104         BaseVec::operator[](axis) = 1; }
00105 
00107     UnitVec& operator=(const UnitVec& u) 
00108     {   BaseVec::operator=(static_cast<const BaseVec&>(u)); 
00109         return *this; }
00110 
00113     template <int S2> UnitVec& operator=(const UnitVec<P,S2>& u) 
00114     {   BaseVec::operator=(static_cast<const typename UnitVec<P,S2>::BaseVec&>(u));
00115         return *this; }
00116 
00118     const BaseVec& asVec3() const {return static_cast<const BaseVec&>(*this);}
00119 
00120     // Override Vec3 methods which preserve length. These return a 
00121     // packed UnitVec regardless of our stride.
00122 
00125     UnitVec<P,1> negate()    const {return UnitVec<P,1>(-asVec3(),true);}
00128     UnitVec<P,1> operator-() const {return negate();}
00129 
00132     const TransposeType& operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
00135     TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
00136 
00137     // We have to define these here so that the non-const ones won't be
00138     // inherited. We don't trust anyone to write on one element of a UnitVec!
00139 
00143     const RealP&  operator[](int i) const  { return BaseVec::operator[](i); }
00147     const RealP&  operator()(int i) const  { return BaseVec::operator()(i); }
00148 
00154     UnitVec<P,1> abs() const {return UnitVec<P,1>( asVec3().abs(), true );}
00155 
00159     inline UnitVec<P,1> perp() const;
00160 
00164     UnitVec(const BaseVec& v, bool) : BaseVec(v) {}
00169     template <int S2> UnitVec(const Vec<3,RealP,S2>& v, bool) : BaseVec(v) { }
00170 };
00171 
00172 
00173 template <class P, int S> inline UnitVec<P,1> 
00174 UnitVec<P,S>::perp() const {
00175     // Choose the coordinate axis which makes the largest angle
00176     // with this vector, that is, has the "least u" along it.
00177     const UnitVec<P,1> u(abs());    // reflect to first octant
00178     const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
00179                                      : (u[1] <= u[2] ? 1 : 2);
00180     // Cross returns a Vec3 result which is then normalized.
00181     return UnitVec<P,1>( *this % UnitVec<P,1>(minAxis) );
00182 }
00183 
00184 
00185 //-----------------------------------------------------------------------------
00190 //-----------------------------------------------------------------------------
00191 template <class P, int S>
00192 class UnitRow : public Row<3,P,S> {
00193     typedef P   RealP;
00194 public:
00195     typedef Row<3,P,S>      BaseRow;
00196     typedef UnitVec<P,S>    TransposeType;
00197 
00198     UnitRow() : BaseRow(NTraits<P>::getNaN()) { }
00199 
00201     UnitRow(const UnitRow& u) 
00202     :   BaseRow(static_cast<const BaseRow&>(u)) {}
00203 
00206     template <int S2> UnitRow(const UnitRow<P,S2>& u)
00207     :   BaseRow(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u)) { }
00208 
00210     UnitRow& operator=(const UnitRow& u) 
00211     {   BaseRow::operator=(static_cast<const BaseRow&>(u)); 
00212         return *this; }
00213 
00215     template <int S2> UnitRow& operator=(const UnitRow<P,S2>& u) 
00216     {   BaseRow::operator=(static_cast<const typename UnitRow<P,S2>::BaseRow&>(u));
00217         return *this; }
00218 
00220     explicit UnitRow(const BaseRow& v) : BaseRow(v/v.norm()) {}
00223     template <int S2> 
00224     explicit UnitRow(const Row<3,P,S2>& v) : BaseRow(v/v.norm()) {}
00225 
00228     UnitRow(const RealP& x, const RealP& y, const RealP& z)
00229     :   BaseRow(x,y,z)
00230     {   static_cast<BaseRow&>(*this) /= BaseRow::norm(); }
00231 
00233     explicit UnitRow(int axis) : BaseRow(0) 
00234     {   assert(0 <= axis && axis <= 2);
00235         BaseRow::operator[](axis) = 1; }
00236 
00238     const BaseRow& asRow3() const  {return static_cast<const BaseRow&>(*this);}
00239 
00240     // Override Row3 methods which preserve length. These return the 
00241     // packed UnitRow regardless of our stride.
00242 
00245     UnitRow<P,1> negate()    const  { return UnitRow<P,1>(-asRow3(),true); }
00248     UnitRow<P,1> operator-() const  { return negate();}
00249 
00252     const TransposeType&  operator~() const {return *reinterpret_cast<const TransposeType*>(this);}
00255     TransposeType& operator~() {return *reinterpret_cast<TransposeType*>(this);}
00256 
00257     // We have to define these here so that the non-const ones won't be
00258     // inherited. We don't trust anyone to write on one element of a UnitRow!
00259 
00263     const RealP&  operator[](int i) const  { return BaseRow::operator[](i); }
00267     const RealP&  operator()(int i) const  { return BaseRow::operator()(i); }
00268 
00274     UnitRow<P,1> abs() const {return UnitRow<P,1>(asRow3().abs(),true);}
00275 
00279     inline UnitRow<P,1> perp() const;
00280 
00281     // This constructor is only for our friends whom we trust to
00282     // give us an already-normalized vector.
00283     UnitRow( const BaseRow& v, bool ) : BaseRow(v) { }
00284     template <int S2> UnitRow( const Row<3,P,S2>& v, bool ) : BaseRow(v) { }
00285 };
00286 
00287 template <class P, int S>
00288 inline UnitRow<P,1> UnitRow<P,S>::perp() const {
00289     // Choose the coordinate axis which makes the largest angle
00290     // with this vector, that is, has the "least u" along it.
00291     const UnitRow<P,1> u(abs());    // reflect to first octant
00292     const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2)
00293                                      : (u[1] <= u[2] ? 1 : 2);
00294     // Cross returns a Row3 result which is then normalized.
00295     return UnitRow<P,1>(*this % UnitRow<P,1>(minAxis));
00296 }
00297 
00298 
00299 
00300 //------------------------------------------------------------------------------
00301 }  // End of namespace SimTK
00302 
00303 //--------------------------------------------------------------------------
00304 #endif // SimTK_UNITVEC_H_
00305 //--------------------------------------------------------------------------
00306 
00307 

Generated on Thu Aug 12 16:37:33 2010 for SimTKcore by  doxygen 1.6.1