Simbody
3.4 (development)
|
00001 #ifndef SimTK_UNITVEC_H 00002 #define SimTK_UNITVEC_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 * 00014 * Contributors: Paul Mitiguy * 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 00030 #include "SimTKcommon/SmallMatrix.h" 00031 #include "SimTKcommon/internal/CoordinateAxis.h" 00032 00033 #include <iosfwd> // Forward declaration of iostream 00034 00035 namespace SimTK { 00036 00037 //----------------------------------------------------------------------------- 00038 // Forward declarations. These are templatized by precision P and and stride S 00039 // but always have length 3. TODO: this should be generalized to other lengths. 00040 template <class P, int S> class UnitVec; 00041 template <class P, int S> class UnitRow; 00042 00043 // UnitVec3 is more intelligible name for UnitVec<Real,1>. 00044 typedef UnitVec<Real,1> UnitVec3; 00045 typedef UnitVec<float,1> fUnitVec3; 00046 typedef UnitVec<double,1> dUnitVec3; 00047 00048 //----------------------------------------------------------------------------- 00054 //----------------------------------------------------------------------------- 00055 template <class P, int S> 00056 class UnitVec : public Vec<3,P,S> { 00057 typedef P RealP; 00058 public: 00059 typedef Vec<3,P,S> BaseVec; 00060 typedef UnitRow<P,S> TransposeType; 00061 00064 UnitVec() : BaseVec(NTraits<P>::getNaN()) {} 00065 00068 UnitVec(const UnitVec& u) 00069 : BaseVec( static_cast<const BaseVec&>(u) ) {} 00070 00073 template <int S2> UnitVec(const UnitVec<P,S2>& u) 00074 : BaseVec( static_cast<const typename UnitVec<P,S2>::BaseVec&>(u) ) {} 00075 00077 explicit UnitVec(const BaseVec& v) : BaseVec(v/v.norm()) {} 00080 template <int S2> 00081 explicit UnitVec(const Vec<3,P,S2>& v) : BaseVec(v/v.norm()) {} 00082 00086 UnitVec(const RealP& x, const RealP& y, const RealP& z) : BaseVec(x,y,z) 00087 { static_cast<BaseVec&>(*this) /= BaseVec::norm(); } 00088 00091 UnitVec(const CoordinateAxis& axis) : BaseVec(0) 00092 { BaseVec::operator[](axis) = 1; } 00093 00097 UnitVec(const CoordinateDirection& dir) : BaseVec(0) 00098 { BaseVec::operator[](dir.getAxis()) = RealP(dir.getDirection()); } 00099 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 00176 static const UnitVec& getAs(const RealP* p) 00177 { return *reinterpret_cast<const UnitVec*>(p); } 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 00304 UnitRow( const BaseRow& v, bool ) : BaseRow(v) { } 00309 template <int S2> UnitRow( const Row<3,P,S2>& v, bool ) : BaseRow(v) { } 00310 00316 static const UnitRow& getAs(const RealP* p) 00317 { return *reinterpret_cast<const UnitRow*>(p); } 00318 }; 00319 00320 template <class P, int S> 00321 inline UnitRow<P,1> UnitRow<P,S>::perp() const { 00322 // Choose the coordinate axis which makes the largest angle 00323 // with this vector, that is, has the "least u" along it. 00324 const UnitRow<P,1> u(abs()); // reflect to first octant 00325 const int minAxis = u[0] <= u[1] ? (u[0] <= u[2] ? 0 : 2) 00326 : (u[1] <= u[2] ? 1 : 2); 00327 // Cross returns a Row3 result which is then normalized. 00328 return UnitRow<P,1>(*this % UnitRow<P,1>(minAxis)); 00329 } 00330 00331 00334 template <class P, int S1, int S2> inline bool 00335 operator==(const UnitRow<P,S1>& u1, const UnitRow<P,S2>& u2) 00336 { return u1.asRow3() == u2.asRow3(); } 00337 00341 template <class P, int S1, int S2> inline bool 00342 operator!=(const UnitRow<P,S1>& u1, const UnitRow<P,S2>& u2) 00343 { return !(u1==u2); } 00344 00345 //------------------------------------------------------------------------------ 00346 } // End of namespace SimTK 00347 00348 //-------------------------------------------------------------------------- 00349 #endif // SimTK_UNITVEC_H_ 00350 //-------------------------------------------------------------------------- 00351 00352