Simbody

CoordinateAxis.h

Go to the documentation of this file.
00001 #ifndef SimTK_COORDINATEAXIS_H 
00002 #define SimTK_COORDINATEAXIS_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 and Paul Mitiguy                                  *
00014  * Contributors:                                                              *
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 <cassert>
00039 
00040 namespace SimTK {
00041 
00060 class CoordinateAxis {
00061 public:
00064     explicit CoordinateAxis( int i ) : m_myAxisId(i) {assertIndexIsInRange(i);}
00065 
00067     operator int() const {return m_myAxisId;}
00068 
00073     CoordinateAxis getNextAxis() const 
00074     {   return CoordinateAxis((m_myAxisId+1) % 3); }
00075 
00080     CoordinateAxis getPreviousAxis() const 
00081     {   return CoordinateAxis((m_myAxisId+2) % 3); }
00082 
00090     CoordinateAxis getThirdAxis( const CoordinateAxis& axis2 ) const { 
00091        assert( isDifferentAxis(axis2) );
00092        CoordinateAxis nextAxis = getNextAxis();
00093        return nextAxis.isDifferentAxis(axis2) ? nextAxis : axis2.getNextAxis();
00094     }
00095 
00097     bool isXAxis() const {return m_myAxisId == 0;}
00099     bool isYAxis() const {return m_myAxisId == 1;}
00101     bool isZAxis() const {return m_myAxisId == 2;}
00104     bool isNextAxis( const CoordinateAxis& axis2 ) const
00105     {   return int(getNextAxis()) == int(axis2); }
00108     bool isPreviousAxis( const CoordinateAxis& axis2 ) const
00109     {   return int(getPreviousAxis()) == int(axis2); }
00112     bool isSameAxis( const CoordinateAxis& axis2 ) const
00113     {   return m_myAxisId == int(axis2); }
00115     bool areAllSameAxes( const CoordinateAxis& axis2, const CoordinateAxis &axis3 ) const       
00116     {   return isSameAxis(axis2) && isSameAxis(axis3); }
00119     bool isDifferentAxis( const CoordinateAxis& axis2 ) const                                   
00120     {   return m_myAxisId != int(axis2); }
00124     bool areAllDifferentAxes( const CoordinateAxis& axis2, const CoordinateAxis& axis3 ) const  
00125     {   return isDifferentAxis(axis2) && isDifferentAxis(axis3) && axis2.isDifferentAxis(axis3); }
00129     bool isForwardCyclical( const CoordinateAxis& axis2 ) const                                
00130     {   return isNextAxis(axis2); }
00134     bool isReverseCyclical( const CoordinateAxis& axis2 ) const                                 
00135     {   return isPreviousAxis(axis2); }
00136 
00140     int dotProduct(  const CoordinateAxis& axis2 ) const
00141     {   return isSameAxis(axis2) ? 1 : 0; }
00147     int crossProductSign( const CoordinateAxis& axis2 ) const
00148     {   return isSameAxis(axis2) ? 0 : (isNextAxis(axis2) ? 1 : -1); }
00156     CoordinateAxis crossProductAxis( const CoordinateAxis& axis2 ) const
00157     {   return isSameAxis(axis2) ? CoordinateAxis(m_myAxisId) 
00158                                  : getThirdAxis(axis2); }
00165     CoordinateAxis crossProduct( const CoordinateAxis& axis2, int& sign ) const
00166     {   sign = crossProductSign(axis2); return crossProductAxis(axis2); }
00167 
00170     static const CoordinateAxis& getCoordinateAxis( int i );
00171 
00175     static bool  isIndexInRange( int i )        { return 0<=i && i<=2; }
00178     static void  assertIndexIsInRange( int i )  { assert( isIndexInRange(i) ); } 
00179 
00180     // Forward declarations for subsequent helper classes
00181     class XCoordinateAxis; class YCoordinateAxis; class ZCoordinateAxis;
00182 protected: // turn off doxygen here; these aren't for users
00184     class XTypeAxis{};
00185     class YTypeAxis{};
00186     class ZTypeAxis{};
00187 
00188     CoordinateAxis( const XTypeAxis& ) : m_myAxisId(0) {}
00189     CoordinateAxis( const YTypeAxis& ) : m_myAxisId(1) {}
00190     CoordinateAxis( const ZTypeAxis& ) : m_myAxisId(2) {}
00192 private:            
00193 
00194     int m_myAxisId;
00195 };
00196 
00197 
00198 // Helper classes that allow compile time recognition of axis directions.
00199 class CoordinateAxis::XCoordinateAxis : public CoordinateAxis {
00200   public: XCoordinateAxis() : CoordinateAxis(XTypeAxis()) {}
00201 };
00202 class CoordinateAxis::YCoordinateAxis : public CoordinateAxis {
00203   public: YCoordinateAxis() : CoordinateAxis(YTypeAxis()) {}
00204 };
00205 class CoordinateAxis::ZCoordinateAxis : public CoordinateAxis {
00206   public: ZCoordinateAxis() : CoordinateAxis(ZTypeAxis()) {}
00207 };
00208 
00211 static const CoordinateAxis::XCoordinateAxis  XAxis;
00214 static const CoordinateAxis::YCoordinateAxis  YAxis;
00217 static const CoordinateAxis::ZCoordinateAxis  ZAxis;
00218 
00219 inline const CoordinateAxis& CoordinateAxis::getCoordinateAxis(int i) {
00220     assertIndexIsInRange(i);
00221     return (i==0 ? static_cast<const CoordinateAxis&>(XAxis) 
00222          : (i==1 ? static_cast<const CoordinateAxis&>(YAxis) 
00223                  : static_cast<const CoordinateAxis&>(ZAxis)));
00224 }
00225 
00227 inline bool operator==(const CoordinateAxis& a1, const CoordinateAxis& a2)
00228 {   return a1.isSameAxis(a2); }
00229 
00231 inline bool operator!=(const CoordinateAxis& a1, const CoordinateAxis& a2)
00232 {   return a1.isDifferentAxis(a2); }
00233 
00234 
00249 class CoordinateDirection {
00250 public:
00253     class Negative {};
00254 
00257     CoordinateDirection(const CoordinateAxis& axis)
00258     :   m_axis(axis), m_direction(1) {}
00259 
00262     CoordinateDirection(const CoordinateAxis& axis, Negative)
00263     :   m_axis(axis), m_direction(-1) {}
00264 
00272     CoordinateDirection(const CoordinateAxis& axis, int direction)
00273     :   m_axis(axis), m_direction(direction) 
00274     {   assert(direction==1 || direction==-1); }
00275 
00279     CoordinateAxis getAxis() const {return m_axis;}
00282     int getDirection() const {return m_direction;}
00283 
00286     bool hasSameAxis(const CoordinateDirection& dir2) const
00287     {   return m_axis.isSameAxis(dir2.getAxis()); }
00288 
00292     bool isSameAxisAndDirection(const CoordinateDirection& dir2) const
00293     {   return m_axis==dir2.getAxis() && m_direction==dir2.getDirection(); }
00294 
00298     int dotProduct(  const CoordinateDirection& dir2 ) const
00299     {   if (m_axis != dir2.getAxis()) return 0;
00300         return m_direction == dir2.getDirection() ? 1 : -1; }
00301 
00307     int crossProductSign( const CoordinateDirection& dir2 ) const
00308     {   if (m_axis == dir2.getAxis()) return 0;
00309         return m_axis.crossProductSign(dir2.getAxis())
00310                * m_direction * dir2.getDirection(); }
00311 
00319     CoordinateAxis crossProductAxis( const CoordinateDirection& dir2 ) const
00320     {   return m_axis.crossProductAxis(dir2.getAxis()); }
00321 
00329     CoordinateAxis crossProduct( const CoordinateDirection& dir2, int& sign ) const
00330     {   sign = crossProductSign(dir2); return crossProductAxis(dir2); }
00331 
00332     // Local class declarations for helper classes.
00333     class NegXDirection; class NegYDirection; class NegZDirection;
00334 private:
00335     CoordinateAxis m_axis;      // XAxis, YAxis, or ZAxis
00336     int            m_direction; // 1 or -1
00337 };
00338 
00339 
00340 // Helper classes that allow compile time recognition of negative axis
00341 // directions.
00342 class CoordinateDirection::NegXDirection : public CoordinateDirection {
00343   public: NegXDirection() : CoordinateDirection(XAxis,Negative()) {}
00344 };
00345 class CoordinateDirection::NegYDirection : public CoordinateDirection {
00346   public: NegYDirection() : CoordinateDirection(YAxis,Negative()) {}
00347 };
00348 class CoordinateDirection::NegZDirection : public CoordinateDirection {
00349   public: NegZDirection() : CoordinateDirection(ZAxis,Negative()) {}
00350 };
00351 
00352 // Predefine constants for the negative X,Y,Z directions.
00353 static const CoordinateDirection::NegXDirection  NegXAxis;
00354 static const CoordinateDirection::NegYDirection  NegYAxis;
00355 static const CoordinateDirection::NegZDirection  NegZAxis;
00356 
00358 inline bool operator==(const CoordinateDirection& d1, 
00359                        const CoordinateDirection& d2)
00360 {   return d1.isSameAxisAndDirection(d2); }
00361 
00363 inline bool operator!=(const CoordinateDirection& d1, 
00364                        const CoordinateDirection& d2)
00365 {   return !d1.isSameAxisAndDirection(d2); }
00366 
00369 inline const CoordinateDirection::NegXDirection&
00370 operator-(const CoordinateAxis::XCoordinateAxis&){return NegXAxis;}
00373 inline const CoordinateDirection::NegYDirection&
00374 operator-(const CoordinateAxis::YCoordinateAxis&){return NegYAxis;}
00377 inline const CoordinateDirection::NegZDirection&
00378 operator-(const CoordinateAxis::ZCoordinateAxis&){return NegZAxis;}
00379 
00382 inline CoordinateDirection
00383 operator-(const CoordinateAxis& axis)
00384 {   return CoordinateDirection(axis,CoordinateDirection::Negative()); }
00385 
00388 inline CoordinateDirection
00389 operator+(const CoordinateAxis& axis)
00390 {   return CoordinateDirection(axis); }
00391 
00394 inline const CoordinateAxis::XCoordinateAxis&
00395 operator-(const CoordinateDirection::NegXDirection&){return XAxis;}
00398 inline const CoordinateAxis::YCoordinateAxis&
00399 operator-(const CoordinateDirection::NegYDirection&){return YAxis;}
00402 inline const CoordinateAxis::ZCoordinateAxis&
00403 operator-(const CoordinateDirection::NegZDirection&){return ZAxis;}
00404 
00407 inline CoordinateDirection
00408 operator-(const CoordinateDirection& dir)
00409 {   return CoordinateDirection(dir.getAxis(), -dir.getDirection()); }
00410 
00411 }  // End of namespace
00412 
00413 #endif // SimTK_COORDINATEAXIS_H
00414 
00415 
00416 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines