Simbody  3.4 (development)
Transform.h
Go to the documentation of this file.
00001 #ifndef SimTK_SimTKCOMMON_TRANSFORM_H 
00002 #define SimTK_SimTKCOMMON_TRANSFORM_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 
00027 //-----------------------------------------------------------------------------
00028 #include "SimTKcommon/SmallMatrix.h"
00029 #include "SimTKcommon/internal/BigMatrix.h"
00030 #include "SimTKcommon/internal/UnitVec.h"
00031 #include "SimTKcommon/internal/Quaternion.h"
00032 #include "SimTKcommon/internal/Rotation.h"
00033 //-----------------------------------------------------------------------------
00034 #include <iosfwd>  // Forward declaration of iostream
00035 //-----------------------------------------------------------------------------
00036 
00037 
00038 //-----------------------------------------------------------------------------
00039 namespace SimTK {
00040 
00041 //-----------------------------------------------------------------------------
00042 // Forward declarations (everything is templatized by precision).
00043 template <class P> class Transform_;
00044 template <class P> class InverseTransform_;
00045 
00046 typedef Transform_<Real>    Transform;
00047 typedef Transform_<float>   fTransform;
00048 typedef Transform_<double>  dTransform;
00049 
00050 
00051 //-----------------------------------------------------------------------------
00106 //-----------------------------------------------------------------------------
00107 template <class P>
00108 class Transform_ {
00109 public:
00111     Transform_() : R_BF(),  p_BF(0) { }
00112 
00114     Transform_( const Rotation_<P>& R, const Vec<3,P>& p ) : R_BF(R), p_BF(p) { }
00115 
00118     Transform_( const Rotation_<P>& R ) : R_BF(R), p_BF(0) { }
00119 
00122     Transform_( const Vec<3,P>& p ) : R_BF(),  p_BF(p) { }
00123 
00124     // default copy, assignment, destructor
00125 
00133     // (Definition is below after InverseTransform is declared.)
00134     inline Transform_&  operator=( const InverseTransform_<P>& X );
00135 
00138     template <int S>
00139     Transform_& operator+=(const Vec<3,P,S>& offset_B)
00140     {   p_BF += offset_B; return *this; }
00141 
00144     template <int S>
00145     Transform_& operator-=(const Vec<3,P,S>& offset_B)
00146     {   p_BF -= offset_B; return *this; }
00147 
00151     Transform_&  set( const Rotation_<P>& R, const Vec<3,P>& p ) { p_BF=p; R_BF=R; return *this; }
00152 
00156     Transform_&  setToZero()  { R_BF.setRotationToIdentityMatrix();  p_BF = P(0);  return *this; }
00157 
00162     Transform_&  setToNaN()  { R_BF.setRotationToNaN();  p_BF.setToNaN();  return *this; }
00163 
00166     const InverseTransform_<P>&  invert() const  { return *reinterpret_cast<const InverseTransform_<P>*>(this); }
00167 
00170     InverseTransform_<P>&  updInvert()  { return *reinterpret_cast<InverseTransform_<P>*>(this); }
00171 
00173     const InverseTransform_<P>&  operator~() const  {return invert();}
00174 
00176     InverseTransform_<P>&        operator~()        {return updInvert();}
00177 
00180     Transform_ compose(const Transform_& X_FY) const {
00181         return Transform_( R_BF * X_FY.R(),  p_BF + R_BF * X_FY.p() );
00182     }
00183 
00189     // (Definition is below after InverseTransform_ is declared.)
00190     inline Transform_  compose( const InverseTransform_<P>& X_FY ) const;
00191 
00195     Vec<3,P>  xformFrameVecToBase( const Vec<3,P>& vF ) const {return R_BF*vF;}
00196 
00200     Vec<3,P>  xformBaseVecToFrame( const Vec<3,P>& vB ) const  { return ~R_BF*vB; }
00201 
00205     Vec<3,P>  shiftFrameStationToBase( const Vec<3,P>& sF ) const 
00206     {   return p_BF + xformFrameVecToBase(sF); }
00207 
00211     Vec<3,P>  shiftBaseStationToFrame( const Vec<3,P>& sB ) const 
00212     {   return xformBaseVecToFrame(sB - p_BF); }
00213 
00215     const Rotation_<P>&  R() const  { return R_BF; }
00216 
00218     Rotation_<P>&  updR()           { return R_BF; }
00219 
00222     const typename Rotation_<P>::ColType&  x() const  { return R().x(); }
00225     const typename Rotation_<P>::ColType&  y() const  { return R().y(); }
00228     const typename Rotation_<P>::ColType&  z() const  { return R().z(); }
00229 
00232     const InverseRotation_<P>&  RInv() const  { return ~R_BF; }
00233 
00236     InverseRotation_<P>&  updRInv()  { return ~R_BF; }
00237 
00239     const Vec<3,P>&  p() const  { return p_BF; }
00240 
00243     Vec<3,P>&  updP()  { return p_BF; }
00244 
00249     Transform_<P>&  setP( const Vec<3,P>& p )  { p_BF=p; return *this; }
00250 
00254     Vec<3,P>  pInv() const  { return -(~R_BF*p_BF); }
00255 
00263     Transform_<P>&  setPInv( const Vec<3,P>& p_FB )  { p_BF = -(R_BF*p_FB); return *this; }
00264 
00268     const Mat<3,4,P>&  asMat34() const  { return Mat<3,4,P>::getAs(reinterpret_cast<const P*>(this)); }
00269 
00271     Mat<3,4,P>  toMat34() const  { return asMat34(); }
00272 
00274     Mat<4,4,P> toMat44() const {
00275         Mat<4,4,P> tmp;
00276         tmp.template updSubMat<3,4>(0,0) = asMat34();
00277         tmp[3]                  = Row<4,P>(0,0,0,1);
00278         return tmp;
00279     }
00280 
00281     // OBSOLETE -- alternate name for p
00282     const Vec<3,P>& T() const {return p();}
00283     Vec<3,P>&  updT()  {return updP();}
00284 
00285 private:
00286     //TODO: these might not pack correctly; should use an array of 12 Reals.
00287     Rotation_<P> R_BF;   // rotation matrix that expresses F's axes in R
00288     Vec<3,P>     p_BF;   // location of F's origin measured from B's origin, expressed in B 
00289 };
00290 
00291 
00292 //-----------------------------------------------------------------------------
00304 //-----------------------------------------------------------------------------
00305 template <class P>
00306 class InverseTransform_ {
00307 public:
00309     InverseTransform_() : R_FB(), p_FB(0) { }
00310 
00311     // default copy, assignment, destructor
00312 
00314     operator Transform_<P>() const  { return Transform_<P>( R(), p() ); }
00315 
00316     // Assignment from Transform. This means that the inverse
00317     // transform we're assigning to must end up with the same meaning
00318     // as the inverse transform X has, so we'll need:
00319     //          p* == X.pInv()
00320     //          R* == X.RInv()
00321     // Cost: one frame conversion and a negation for pInv, 18 flops.
00322     InverseTransform_&  operator=( const Transform_<P>& X ) {
00323         // Be careful to do this in the right order in case X and this
00324         // are the same object, i.e. ~X = X which is weird but has
00325         // the same meaning as X = ~X, i.e. invert X in place.
00326         p_FB = X.pInv(); // This might change X.p ...
00327         R_FB = X.RInv(); // ... but this doesn't depend on X.p.
00328         return *this;
00329     }
00330 
00331     // Inverting one of these just recasts it back to a Transform_<P>.
00332     const Transform_<P>&  invert() const  { return *reinterpret_cast<const Transform_<P>*>(this); }
00333     Transform_<P>&  updInvert()           { return *reinterpret_cast<Transform_<P>*>(this); }
00334 
00335     // Overload transpose to mean inversion.
00336     const Transform_<P>&  operator~() const  { return invert(); }
00337     Transform_<P>&        operator~()        { return updInvert(); }
00338 
00339     // Return X_BY=X_BF*X_FY, where X_BF (this) is represented here as ~X_FB. This
00340     // costs exactly the same as a composition of two Transforms (63 flops).
00341     Transform_<P>  compose(const Transform_<P>& X_FY) const {
00342         return Transform_<P>( ~R_FB * X_FY.R(),  ~R_FB *(X_FY.p() - p_FB) );
00343     }
00344     // Return X_BY=X_BF*X_FY, but now both xforms are represented by their inverses.
00345     // This costs one extra vector transformation and a negation (18 flops) more
00346     // than a composition of two Transforms, for a total of 81 flops.
00347     Transform_<P>  compose(const InverseTransform_<P>& X_FY) const { 
00348         return Transform_<P>(  ~R_FB * X_FY.R(),  ~R_FB *(X_FY.p() - p_FB)  ); 
00349     }
00350 
00351     // Forward and inverse vector transformations cost the same here as
00352     // for a Transform_<P> (or for that matter, a Rotation_<P>): 15 flops.
00353     Vec<3,P>  xformFrameVecToBase(const Vec<3,P>& vF) const {return ~R_FB*vF;}
00354     Vec<3,P>  xformBaseVecToFrame(const Vec<3,P>& vB) const {return  R_FB*vB;}
00355 
00356     // Forward and inverse station shift & transform cost the same here as for a Transform_<P>: 18 flops.
00357     Vec<3,P>  shiftFrameStationToBase(const Vec<3,P>& sF) const  { return ~R_FB*(sF-p_FB); }
00358     Vec<3,P>  shiftBaseStationToFrame(const Vec<3,P>& sB) const  { return R_FB*sB + p_FB; }
00359     
00360     const InverseRotation_<P>&  R() const  {return ~R_FB;}
00361     InverseRotation_<P>&        updR()     {return ~R_FB;}
00362 
00363     const typename InverseRotation_<P>::ColType&  x() const  {return R().x();}
00364     const typename InverseRotation_<P>::ColType&  y() const  {return R().y();}
00365     const typename InverseRotation_<P>::ColType&  z() const  {return R().z();}
00366 
00367     const Rotation_<P>&  RInv() const  {return R_FB;}
00368     Rotation_<P>&        updRInv()     {return R_FB;}
00369 
00373     Vec<3,P>  p() const  { return -(~R_FB*p_FB); }
00374 
00375 
00376     // no updP lvalue
00377 
00378     // Sorry, can't update translation as an lvalue, but here we
00379     // want -(R_BF*p_FB)=p_BF => p_FB=-(R_FB*p_BF). Cost: 18 flops.
00380     void  setP( const Vec<3,P>& p_BF )  { p_FB = -(R_FB*p_BF); }
00381 
00382     // Inverse translation is free.
00383     const Vec<3,P>&  pInv() const              { return p_FB; }
00384     void         setPInv( const Vec<3,P>& p )  { p_FB = p; }
00385 
00388     Mat<3,4,P>  toMat34() const  { return Transform_<P>(*this).asMat34(); }
00389 
00391     Mat<4,4,P>  toMat44() const  { return Transform_<P>(*this).toMat44(); }
00392 
00393     // OBSOLETE -- alternate name for p.
00394     Vec<3,P> T() const {return p();}
00395 
00396 private:
00397     // DATA LAYOUT MUST BE IDENTICAL TO Transform_<P> !!
00398     // TODO: redo packing here when it is done for Transform_<P>.
00399     Rotation_<P> R_FB; // transpose of our rotation matrix, R_BF
00400     Vec<3,P>     p_FB; // our translation is -(R_BF*p_FB)=-(~R_FB*p_FB)
00401 };
00402 
00408 template <class P, int S> inline Vec<3,P>  
00409 operator*(const Transform_<P>& X_BF,        const Vec<3,P,S>& s_F)  
00410 {   return X_BF.shiftFrameStationToBase(s_F); }
00411 template <class P, int S> inline Vec<3,P>  
00412 operator*(const InverseTransform_<P>& X_BF, const Vec<3,P,S>& s_F)  
00413 {   return X_BF.shiftFrameStationToBase(s_F); }
00414 template <class P, int S> inline Vec<3,P>  
00415 operator*(const Transform_<P>& X_BF,        const Vec<3,negator<P>,S>& s_F)  
00416 {   return X_BF*Vec<3,P>(s_F); }
00417 template <class P, int S> inline Vec<3,P>  
00418 operator*(const InverseTransform_<P>& X_BF, const Vec<3,negator<P>,S>& s_F)  
00419 {   return X_BF*Vec<3,P>(s_F); }
00420 
00423 template <class P, int S> inline Transform_<P>
00424 operator+(const Transform_<P>& X_BF, const Vec<3,P,S>& offset_B)
00425 {   return Transform_<P>(X_BF) += offset_B; }
00428 template <class P, int S> inline Transform_<P>
00429 operator+(const Vec<3,P,S>& offset_B, const Transform_<P>& X_BF)
00430 {   return Transform_<P>(X_BF) += offset_B; }
00431 
00434 template <class P, int S> inline Transform_<P>
00435 operator-(const Transform_<P>& X_BF, const Vec<3,P,S>& offset_B)
00436 {   return Transform_<P>(X_BF) -= offset_B; }
00437 
00438 //-----------------------------------------------------------------------------
00444 template <class P, int S> inline Vec<4,P> 
00445 operator*(const Transform_<P>& X_BF, const Vec<4,P,S>& a_F) {
00446     assert(a_F[3]==0 || a_F[3]==1);
00447     const Vec<3,P,S>& v_F = Vec<3,P,S>::getAs(&a_F[0]); // recast the 1st 3 elements as Vec3
00448 
00449     Vec<4,P> out;
00450     if( a_F[3] == 0 ) { Vec<3,P>::updAs(&out[0]) = X_BF.xformFrameVecToBase(v_F);      out[3] = 0; } 
00451     else              { Vec<3,P>::updAs(&out[0]) = X_BF.shiftFrameStationToBase(v_F);  out[3] = 1; }
00452     return out;
00453 }
00454 
00455 template <class P, int S> inline Vec<4,P> 
00456 operator*(const InverseTransform_<P>& X_BF, const Vec<4,P,S>& a_F ) {
00457     assert(a_F[3]==0 || a_F[3]==1);
00458     const Vec<3,P,S>& v_F = Vec<3,P,S>::getAs(&a_F[0]); // recast the 1st 3 elements as Vec3
00459 
00460     Vec<4,P> out;
00461     if( a_F[3] == 0 ) { Vec<3,P>::updAs(&out[0]) = X_BF.xformFrameVecToBase(v_F);      out[3] = 0; } 
00462     else              { Vec<3,P>::updAs(&out[0]) = X_BF.shiftFrameStationToBase(v_F);  out[3] = 1; }
00463     return out;
00464 }
00465 template <class P, int S> inline Vec<4,P>  
00466 operator*(const Transform_<P>& X_BF,        const Vec<4,negator<P>,S>& s_F)  {return X_BF*Vec<4,P>(s_F);}
00467 template <class P, int S> inline Vec<4,P>  
00468 operator*(const InverseTransform_<P>& X_BF, const Vec<4,negator<P>,S>& s_F)  {return X_BF*Vec<4,P>(s_F);}
00469 //-----------------------------------------------------------------------------
00470 
00474 template <class P, class E> inline Vector_<E> 
00475 operator*(const Transform_<P>& X, const VectorBase<E>& v) {
00476     Vector_<E> result(v.size());
00477     for (int i = 0; i < v.size(); ++i)
00478         result[i] = X*v[i];
00479     return result;
00480 }
00481 template <class P, class E> inline Vector_<E> 
00482 operator*(const VectorBase<E>& v, const Transform_<P>& X) {
00483     Vector_<E> result(v.size());
00484     for (int i = 0; i < v.size(); ++i)
00485         result[i] = X*v[i];
00486     return result;
00487 }
00488 template <class P, class E> inline RowVector_<E> 
00489 operator*(const Transform_<P>& X, const RowVectorBase<E>& v) {
00490     RowVector_<E> result(v.size());
00491     for (int i = 0; i < v.size(); ++i)
00492         result[i] = X*v[i];
00493     return result;
00494 }
00495 template <class P, class E> inline RowVector_<E> 
00496 operator*(const RowVectorBase<E>& v, const Transform_<P>& X) {
00497     RowVector_<E> result(v.size());
00498     for (int i = 0; i < v.size(); ++i)
00499         result[i] = X*v[i];
00500     return result;
00501 }
00502 template <class P, class E> inline Matrix_<E> 
00503 operator*(const Transform_<P>& X, const MatrixBase<E>& v) {
00504     Matrix_<E> result(v.nrow(), v.ncol());
00505     for (int i = 0; i < v.nrow(); ++i)
00506         for (int j = 0; j < v.ncol(); ++j)
00507             result(i, j) = X*v(i, j);
00508     return result;
00509 }
00510 template <class P, class E> inline Matrix_<E> 
00511 operator*(const MatrixBase<E>& v, const Transform_<P>& X) {
00512     Matrix_<E> result(v.nrow(), v.ncol());
00513     for (int i = 0; i < v.nrow(); ++i)
00514         for (int j = 0; j < v.ncol(); ++j)
00515             result(i, j) = X*v(i, j);
00516     return result;
00517 }
00518 template <class P, int N, class E, int S> inline Vec<N,E> 
00519 operator*(const Transform_<P>& X, const Vec<N,E,S>& v) {
00520     Vec<N,E> result;
00521     for (int i = 0; i < N; ++i)
00522         result[i] = X*v[i];
00523     return result;
00524 }
00525 template <class P, int N, class E, int S> inline Vec<N,E> 
00526 operator*(const Vec<N,E,S>& v, const Transform_<P>& X) {
00527     Vec<N,E> result;
00528     for (int i = 0; i < N; ++i)
00529         result[i] = X*v[i];
00530     return result;
00531 }
00532 template <class P, int N, class E, int S> inline Row<N,E> 
00533 operator*(const Transform_<P>& X, const Row<N,E,S>& v) {
00534     Row<N,E> result;
00535     for (int i = 0; i < N; ++i)
00536         result[i] = X*v[i];
00537     return result;
00538 }
00539 template <class P, int N, class E, int S> inline Row<N,E> 
00540 operator*(const Row<N,E,S>& v, const Transform_<P>& X) {
00541     Row<N,E> result;
00542     for (int i = 0; i < N; ++i)
00543         result[i] = X*v[i];
00544     return result;
00545 }
00546 template <class P, int M, int N, class E, int CS, int RS> inline Mat<M,N,E> 
00547 operator*(const Transform_<P>& X, const Mat<M,N,E,CS,RS>& v) {
00548     Mat<M,N,E> result;
00549     for (int i = 0; i < M; ++i)
00550         for (int j = 0; j < N; ++j)
00551             result(i, j) = X*v(i, j);
00552     return result;
00553 }
00554 template <class P, int M, int N, class E, int CS, int RS> inline Mat<M,N,E> 
00555 operator*(const Mat<M,N,E,CS,RS>& v, const Transform_<P>& X) {
00556     Mat<M,N,E> result;
00557     for (int i = 0; i < M; ++i)
00558         for (int j = 0; j < N; ++j)
00559             result(i, j) = X*v(i, j);
00560     return result;
00561 }
00562 
00563 // These Transform definitions had to wait for InverseTransform to be declared.
00564 
00565 template <class P> inline Transform_<P>&
00566 Transform_<P>::operator=( const InverseTransform_<P>& X ) {
00567     // Be careful to do this in the right order in case X and this
00568     // are the same object, i.e. we're doing X = ~X, inverting X in place.
00569     p_BF = X.p(); // This might change X.p ...
00570     R_BF = X.R(); // ... but this doesn't depend on X.p.
00571     return *this;
00572 }
00573 
00574 template <class P> inline Transform_<P>
00575 Transform_<P>::compose( const InverseTransform_<P>& X_FY ) const {
00576     return Transform_<P>( R_BF * X_FY.R(), p_BF + R_BF * X_FY.p() );
00577 }
00578 
00582 template <class P> inline Transform_<P>
00583 operator*(const Transform_<P>& X1,        const Transform_<P>& X2)         {return X1.compose(X2);}
00584 template <class P> inline Transform_<P>
00585 operator*(const Transform_<P>& X1,        const InverseTransform_<P>& X2)  {return X1.compose(X2);}
00586 template <class P> inline Transform_<P>
00587 operator*(const InverseTransform_<P>& X1, const Transform_<P>& X2)         {return X1.compose(X2);}
00588 template <class P> inline Transform_<P>
00589 operator*(const InverseTransform_<P>& X1, const InverseTransform_<P>& X2)  {return X1.compose(X2);}
00590 
00594 template <class P> inline bool
00595 operator==(const Transform_<P>& X1,        const Transform_<P>& X2)         {return X1.R()==X2.R() && X1.p()==X2.p();}
00596 template <class P> inline bool
00597 operator==(const InverseTransform_<P>& X1, const InverseTransform_<P>& X2)  {return X1.R()==X2.R() && X1.p()==X2.p();}
00598 template <class P> inline bool
00599 operator==(const Transform_<P>& X1,        const InverseTransform_<P>& X2)  {return X1.R()==X2.R() && X1.p()==X2.p();}
00600 template <class P> inline bool
00601 operator==(const InverseTransform_<P>& X1, const Transform_<P>& X2)         {return X1.R()==X2.R() && X1.p()==X2.p();}
00602 
00605 template <class P> SimTK_SimTKCOMMON_EXPORT std::ostream&
00606 operator<<(std::ostream&, const Transform_<P>&);
00609 template <class P> SimTK_SimTKCOMMON_EXPORT std::ostream&
00610 operator<<(std::ostream&, const InverseTransform_<P>&);
00611 
00612 
00613 
00614 //------------------------------------------------------------------------------
00615 }  // End of namespace SimTK
00616 
00617 //--------------------------------------------------------------------------
00618 #endif // SimTK_SimTKCOMMON_TRANSFORM_H
00619 //--------------------------------------------------------------------------
00620 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines