CoordinateAxis.h

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 // File:     CoordinateAxis.h
00003 // Class:    CoordinateAxis 
00004 // Parent:   None
00005 // Purpose:  Converts XAxis, YAxis, ZAxis to 0, 1, 2 - but with the ability
00006 //           for the compiler to differentiate the types and method signatures.
00007 //-----------------------------------------------------------------------------
00008 #ifndef SIMTK_COORDINATEAXIS_H 
00009 #define SIMTK_COORDINATEAXIS_H 
00010 
00011 /* -------------------------------------------------------------------------- *
00012  *                      SimTK Core: SimTK Simmatrix(tm)                       *
00013  * -------------------------------------------------------------------------- *
00014  * This is part of the SimTK Core biosimulation toolkit originating from      *
00015  * Simbios, the NIH National Center for Physics-Based Simulation of           *
00016  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
00017  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
00018  *                                                                            *
00019  * Portions copyright (c) 2005-7 Stanford University and the Authors.         *
00020  * Authors: Michael Sherman and Paul Mitiguy                                  *
00021  * Contributors:                                                              *
00022  *                                                                            *
00023  * Permission is hereby granted, free of charge, to any person obtaining a    *
00024  * copy of this software and associated documentation files (the "Software"), *
00025  * to deal in the Software without restriction, including without limitation  *
00026  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
00027  * and/or sell copies of the Software, and to permit persons to whom the      *
00028  * Software is furnished to do so, subject to the following conditions:       *
00029  *                                                                            *
00030  * The above copyright notice and this permission notice shall be included in *
00031  * all copies or substantial portions of the Software.                        *
00032  *                                                                            *
00033  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
00034  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
00035  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
00036  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
00037  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
00038  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
00039  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
00040  * -------------------------------------------------------------------------- */
00041 
00042 //-----------------------------------------------------------------------------
00043 #include <cassert>
00044 
00045 //-----------------------------------------------------------------------------
00046 namespace SimTK {
00047 
00048 //-----------------------------------------------------------------------------
00049 // These classes allow the compiler to identify specific arguments as types, i.e.,
00050 // XAxis is a specific type of class and allows the compiler to match to a specific method.
00051 // In addition, these classes allow easy conversion of XAxis to 0, YAxis to 1, ZAxis to 2.
00052 //-----------------------------------------------------------------------------
00053 class CoordinateAxis {
00054 public:
00055     // This typecasts CoordinateAxis into an int
00056     operator int() const  { return myAxisId; }
00057 
00058     // XAxis.getNextAxis()  returns YAxis; 
00059     // YAxis.getNextAxis()  returns ZAxis; 
00060     // ZAxis.getNextAxis()  returns XAxis;
00061     CoordinateAxis  getNextAxis() const     { return CoordinateAxis( (myAxisId+1) % 3 ); }
00062 
00063     // XAxis.getPreviousAxis()  returns ZAxis; 
00064     // YAxis.getPreviousAxis()  returns XAxis; 
00065     // ZAxis.getPreviousAxis()  returns YAxis;
00066     CoordinateAxis  getPreviousAxis() const { return CoordinateAxis( (myAxisId+2) % 3 ); }
00067 
00068     // XAxis.getThirdAxis(YAxis) returns ZAxis; 
00069     // XAxis.getThirdAxis(ZAxis) returns YAxis; 
00070     // YAxis.getThirdAxis(ZAxis) returns XAxis;
00071     CoordinateAxis  getThirdAxis( const CoordinateAxis& axis2 ) const { 
00072        assert( isDifferentAxis(axis2) );
00073        CoordinateAxis nextAxis = getNextAxis();
00074        return nextAxis.isDifferentAxis(axis2) ? nextAxis : axis2.getNextAxis();
00075        }
00076 
00077     // Compare various axes.
00078     bool  isXAxis() const   { return myAxisId == 0; }
00079     bool  isYAxis() const   { return myAxisId == 1; }
00080     bool  isZAxis() const   { return myAxisId == 2; }
00081     bool  isNextAxis( const CoordinateAxis& axis2 ) const                                        { return int(getNextAxis()) == int(axis2); }
00082     bool  isPreviousAxis( const CoordinateAxis& axis2 ) const                                    { return int(getPreviousAxis()) == int(axis2); }
00083     bool  isSameAxis( const CoordinateAxis& axis2 ) const                                        { return myAxisId == int(axis2); }
00084     bool  areAllSameAxes( const CoordinateAxis& axis2, const CoordinateAxis &axis3 ) const       { return isSameAxis(axis2) && isSameAxis(axis3); }
00085     bool  isDifferentAxis( const CoordinateAxis& axis2 ) const                                   { return myAxisId != int(axis2); }
00086     bool  areAllDifferentAxes( const CoordinateAxis& axis2, const CoordinateAxis& axis3 ) const  { return isDifferentAxis(axis2) && isDifferentAxis(axis3) && axis2.isDifferentAxis(axis3); }
00087     bool  isForwardCyclical( const CoordinateAxis& axis2 ) const                                 { return isNextAxis(axis2); }
00088     bool  isReverseCyclical( const CoordinateAxis& axis2 ) const                                 { return isPreviousAxis(axis2); }
00089 
00090     // Quasi dot-product and cross-product
00091     int  dotProduct(  const CoordinateAxis& axis2 ) const                         { return isSameAxis(axis2) ? 1 : 0; }
00092     int  crossProductSign( const CoordinateAxis& axis2 ) const                    { return isSameAxis(axis2) ? 0 : (isNextAxis(axis2) ? 1 : -1); }
00093     CoordinateAxis  crossProductAxis( const CoordinateAxis& axis2 ) const         { return isSameAxis(axis2) ? CoordinateAxis(myAxisId) : getThirdAxis(axis2); }
00094     CoordinateAxis  crossProduct( const CoordinateAxis& axis2, int& sign ) const  { sign = crossProductSign(axis2);  return crossProductAxis(axis2); }
00095 
00096     // Get the appropriate CoordinateAxis
00097     // Check whether or not an index is in proper range
00098     static CoordinateAxis  getCoordinateAxis( int i )  { assertIndexIsInRange(i);  return (i==0) ? CoordinateAxis(XTypeAxis()) : ((i==1) ? CoordinateAxis(YTypeAxis()) : CoordinateAxis(ZTypeAxis()) ); }
00099     static bool  isIndexInRange( int i )               { return i>=0 && i<=2; }
00100     static void  assertIndexIsInRange( int i )         { assert( isIndexInRange(i) ); } 
00101 
00102     // Forward declarations for subsequent helper classes
00103     class XCoordinateAxis; class YCoordinateAxis; class ZCoordinateAxis;
00104 
00105 protected:
00106     // Declaration of very simple classes
00107     class XTypeAxis{}; class YTypeAxis{}; class ZTypeAxis{};
00108 
00109     CoordinateAxis( const XTypeAxis& ) : myAxisId(0) {}
00110     CoordinateAxis( const YTypeAxis& ) : myAxisId(1) {}
00111     CoordinateAxis( const ZTypeAxis& ) : myAxisId(2) {}
00112 private:            
00113     explicit CoordinateAxis( int i ) : myAxisId(i) { assertIndexIsInRange(i); }
00114 
00115     int myAxisId;
00116 };
00117 
00118 
00119 // Helper classes that make it possible to treat an Axis like an integer
00120 class CoordinateAxis::XCoordinateAxis : public CoordinateAxis {
00121   public: XCoordinateAxis() : CoordinateAxis(XTypeAxis()) {}
00122 };
00123 class CoordinateAxis::YCoordinateAxis : public CoordinateAxis {
00124   public: YCoordinateAxis() : CoordinateAxis(YTypeAxis()) {}
00125 };
00126 class CoordinateAxis::ZCoordinateAxis : public CoordinateAxis {
00127   public: ZCoordinateAxis() : CoordinateAxis(ZTypeAxis()) {}
00128 };
00129 
00130 
00131 // Predefine constants XAxis, YAxis, ZAxis which implicitly convert to integers 0, 1, 2 respectively.
00132 static const CoordinateAxis::XCoordinateAxis  XAxis;
00133 static const CoordinateAxis::YCoordinateAxis  YAxis;
00134 static const CoordinateAxis::ZCoordinateAxis  ZAxis;
00135 
00136 
00137 //------------------------------------------------------------------------------
00138 }  // End of namespace
00139 
00140 //--------------------------------------------------------------------------
00141 #endif // SIMTK_COORDINATEAXIS_H_
00142 //--------------------------------------------------------------------------
00143 
00144 

Generated on Fri Sep 26 07:44:09 2008 for SimTKcore by  doxygen 1.5.6