00001
00002
00003
00004
00005
00006
00007 #ifndef SimTK_TRANSFORM_H
00008 #define SimTK_TRANSFORM_H
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SimTKcommon/SmallMatrix.h"
00043 #include "SimTKcommon/internal/BigMatrix.h"
00044 #include "SimTKcommon/internal/UnitVec.h"
00045 #include "SimTKcommon/internal/Quaternion.h"
00046 #include "SimTKcommon/internal/Rotation.h"
00047
00048 #include <iosfwd>
00049
00050
00051
00052
00053 namespace SimTK {
00054
00055
00056
00057 class InverseTransform;
00058
00059
00060
00119
00120 class Transform {
00121 public:
00123 Transform() : R_BF(), T_BF(0) { }
00124
00126 Transform( const Rotation& R, const Vec3& T ) : R_BF(R), T_BF(T) { }
00127
00130 Transform( const Rotation& R ) : R_BF(R), T_BF(0) { }
00131
00134 Transform( const Vec3& T ) : R_BF(), T_BF(T) { }
00135
00136
00137
00145
00146 inline Transform& operator=( const InverseTransform& X );
00147
00151 Transform& set( const Rotation& R, const Vec3& T ) { T_BF=T; R_BF=R; return *this; }
00152
00156 Transform& setToZero() { R_BF.setRotationToIdentityMatrix(); T_BF = 0.; return *this; }
00157
00162 Transform& setToNaN() { R_BF.setRotationToNaN(); T_BF.setToNaN(); return *this; }
00163
00166 const InverseTransform& invert() const { return *reinterpret_cast<const InverseTransform*>(this); }
00167
00170 InverseTransform& updInvert() { return *reinterpret_cast<InverseTransform*>(this); }
00171
00173 const InverseTransform& operator~() const {return invert();}
00174
00176 InverseTransform& operator~() {return updInvert();}
00177
00180 Transform compose(const Transform& X_FY) const {
00181 return Transform( R_BF * X_FY.R(), T_BF + R_BF * X_FY.T() );
00182 }
00183
00189
00190 inline Transform compose( const InverseTransform& X_FY ) const;
00191
00195 Vec3 xformFrameVecToBase( const Vec3& vF ) const {return R_BF*vF;}
00196
00200 Vec3 xformBaseVecToFrame( const Vec3& vB ) const { return ~R_BF*vB; }
00201
00205 Vec3 shiftFrameStationToBase( const Vec3& sF ) const { return T_BF + xformFrameVecToBase(sF); }
00206
00210 Vec3 shiftBaseStationToFrame( const Vec3& sB ) const { return xformBaseVecToFrame(sB - T_BF); }
00211
00213 const Rotation& R() const { return R_BF; }
00214
00216 Rotation& updR() { return R_BF; }
00217
00220 const Rotation::ColType& x() const { return R().x(); }
00223 const Rotation::ColType& y() const { return R().y(); }
00226 const Rotation::ColType& z() const { return R().z(); }
00227
00230 const InverseRotation& RInv() const { return ~R_BF; }
00231
00234 InverseRotation& updRInv() { return ~R_BF; }
00235
00237 const Vec3& T() const { return T_BF; }
00238
00241 Vec3& updT() { return T_BF; }
00242
00247 Transform& setT( const Vec3& T ) { T_BF=T; return *this; }
00248
00252 Vec3 TInv() const { return -(~R_BF*T_BF); }
00253
00261 Transform& setTInv( const Vec3& T_FB ) { T_BF = -(R_BF*T_FB); return *this; }
00262
00266 const Mat34& asMat34() const { return Mat34::getAs(reinterpret_cast<const Real*>(this)); }
00267
00269 Mat34 toMat34() const { return asMat34(); }
00270
00272 Mat44 toMat44() const {
00273 Mat44 tmp;
00274 tmp.updSubMat<3,4>(0,0) = asMat34();
00275 tmp[3] = Row4(0,0,0,1);
00276 return tmp;
00277 }
00278 private:
00279
00280 Rotation R_BF;
00281 Vec3 T_BF;
00282 };
00283
00284
00285
00298
00299 class InverseTransform {
00300 public:
00301 InverseTransform() : R_FB(), T_FB(0) { }
00302
00303
00304
00305 operator Transform() const { return Transform( R(), T() ); }
00306
00307
00308
00309
00310
00311
00312
00313 InverseTransform& operator=( const Transform& X ) {
00314
00315
00316
00317 T_FB = X.TInv();
00318 R_FB = X.RInv();
00319 return *this;
00320 }
00321
00322
00323 const Transform& invert() const { return *reinterpret_cast<const Transform*>(this); }
00324 Transform& updInvert() { return *reinterpret_cast<Transform*>(this); }
00325
00326
00327 const Transform& operator~() const { return invert(); }
00328 Transform& operator~() { return updInvert(); }
00329
00330
00331
00332 Transform compose(const Transform& X_FY) const {
00333 return Transform( ~R_FB * X_FY.R(), ~R_FB *(X_FY.T() - T_FB) );
00334 }
00335
00336
00337
00338 Transform compose(const InverseTransform& X_FY) const {
00339 return Transform( ~R_FB * X_FY.R(), ~R_FB *(X_FY.T() - T_FB) );
00340 }
00341
00342
00343
00344 Vec3 xformFrameVecToBase(const Vec3& vF) const {return ~R_FB*vF;}
00345 Vec3 xformBaseVecToFrame(const Vec3& vB) const {return R_FB*vB;}
00346
00347
00348 Vec3 shiftFrameStationToBase(const Vec3& sF) const { return ~R_FB*(sF-T_FB); }
00349 Vec3 shiftBaseStationToFrame(const Vec3& sB) const { return R_FB*sB + T_FB; }
00350
00351 const InverseRotation& R() const {return ~R_FB;}
00352 InverseRotation& updR() {return ~R_FB;}
00353
00354 const InverseRotation::ColType& x() const {return R().x();}
00355 const InverseRotation::ColType& y() const {return R().y();}
00356 const InverseRotation::ColType& z() const {return R().z();}
00357
00358 const Rotation& RInv() const {return R_FB;}
00359 Rotation& updRInv() {return R_FB;}
00360
00361
00362 Vec3 T() const { return -(~R_FB*T_FB); }
00363
00364
00365
00366
00367 void setT( const Vec3& T_BF ) { T_FB = -(R_FB*T_BF); }
00368
00369
00370 const Vec3& TInv() const { return T_FB; }
00371 void setTInv( const Vec3& T ) { T_FB = T; }
00372
00375 Mat34 toMat34() const { return Transform(*this).asMat34(); }
00376
00378 Mat44 toMat44() const { return Transform(*this).toMat44(); }
00379
00380 private:
00381
00382
00383 Rotation R_FB;
00384 Vec3 T_FB;
00385 };
00386
00387
00390 inline Vec3 operator*( const Transform& X_BF, const Vec3& s_F ) { return X_BF.shiftFrameStationToBase(s_F); }
00391 inline Vec3 operator*( const InverseTransform& X_BF, const Vec3& s_F ) { return X_BF.shiftFrameStationToBase(s_F); }
00392
00396
00397 inline Vec4 operator*( const Transform& X_BF, const Vec4& a_F ) {
00398 assert(a_F[3]==0 || a_F[3]==1);
00399 const Vec3& v_F = Vec3::getAs(&a_F[0]);
00400
00401 Vec4 out;
00402 if( a_F[3] == 0 ) { Vec3::updAs(&out[0]) = X_BF.xformFrameVecToBase(v_F); out[3] = 0; }
00403 else { Vec3::updAs(&out[0]) = X_BF.shiftFrameStationToBase(v_F); out[3] = 1; }
00404 return out;
00405 }
00406
00407
00408 inline Vec4 operator*( const InverseTransform& X_BF, const Vec4& a_F ) {
00409 assert(a_F[3]==0 || a_F[3]==1);
00410 const Vec3& v_F = Vec3::getAs(&a_F[0]);
00411
00412 Vec4 out;
00413 if( a_F[3] == 0 ) { Vec3::updAs(&out[0]) = X_BF.xformFrameVecToBase(v_F); out[3] = 0; }
00414 else { Vec3::updAs(&out[0]) = X_BF.shiftFrameStationToBase(v_F); out[3] = 1; }
00415 return out;
00416 }
00417
00419
00420 template <class E>
00421 inline Vector_<E> operator*(const Transform& T, const VectorBase<E>& v) {
00422 Vector_<E> result(v.size());
00423 for (int i = 0; i < v.size(); ++i)
00424 result[i] = T*v[i];
00425 return result;
00426 }
00427 template <class E>
00428 inline Vector_<E> operator*(const VectorBase<E>& v, const Transform& T) {
00429 Vector_<E> result(v.size());
00430 for (int i = 0; i < v.size(); ++i)
00431 result[i] = T*v[i];
00432 return result;
00433 }
00434 template <class E>
00435 inline RowVector_<E> operator*(const Transform& T, const RowVectorBase<E>& v) {
00436 RowVector_<E> result(v.size());
00437 for (int i = 0; i < v.size(); ++i)
00438 result[i] = T*v[i];
00439 return result;
00440 }
00441 template <class E>
00442 inline RowVector_<E> operator*(const RowVectorBase<E>& v, const Transform& T) {
00443 RowVector_<E> result(v.size());
00444 for (int i = 0; i < v.size(); ++i)
00445 result[i] = T*v[i];
00446 return result;
00447 }
00448 template <class E>
00449 inline Matrix_<E> operator*(const Transform& T, const MatrixBase<E>& v) {
00450 Matrix_<E> result(v.nrow(), v.ncol());
00451 for (int i = 0; i < v.nrow(); ++i)
00452 for (int j = 0; j < v.ncol(); ++j)
00453 result(i, j) = T*v(i, j);
00454 return result;
00455 }
00456 template <class E>
00457 inline Matrix_<E> operator*(const MatrixBase<E>& v, const Transform& T) {
00458 Matrix_<E> result(v.nrow(), v.ncol());
00459 for (int i = 0; i < v.nrow(); ++i)
00460 for (int j = 0; j < v.ncol(); ++j)
00461 result(i, j) = T*v(i, j);
00462 return result;
00463 }
00464 template <int N, class E>
00465 inline Vec<N,E> operator*(const Transform& T, const Vec<N,E>& v) {
00466 Vec<N,E> result;
00467 for (int i = 0; i < N; ++i)
00468 result[i] = T*v[i];
00469 return result;
00470 }
00471 template <int N, class E>
00472 inline Vec<N,E> operator*(const Vec<N,E>& v, const Transform& T) {
00473 Vec<N,E> result;
00474 for (int i = 0; i < N; ++i)
00475 result[i] = T*v[i];
00476 return result;
00477 }
00478 template <int N, class E>
00479 inline Row<N,E> operator*(const Transform& T, const Row<N,E>& v) {
00480 Row<N,E> result;
00481 for (int i = 0; i < N; ++i)
00482 result[i] = T*v[i];
00483 return result;
00484 }
00485 template <int N, class E>
00486 inline Row<N,E> operator*(const Row<N,E>& v, const Transform& T) {
00487 Row<N,E> result;
00488 for (int i = 0; i < N; ++i)
00489 result[i] = T*v[i];
00490 return result;
00491 }
00492 template <int M, int N, class E>
00493 inline Mat<M,N,E> operator*(const Transform& T, const Mat<M,N,E>& v) {
00494 Mat<M,N,E> result;
00495 for (int i = 0; i < M; ++i)
00496 for (int j = 0; j < N; ++j)
00497 result(i, j) = T*v(i, j);
00498 return result;
00499 }
00500 template <int M, int N, class E>
00501 inline Mat<M,N,E> operator*(const Mat<M,N,E>& v, const Transform& T) {
00502 Mat<M,N,E> result;
00503 for (int i = 0; i < M; ++i)
00504 for (int j = 0; j < N; ++j)
00505 result(i, j) = T*v(i, j);
00506 return result;
00507 }
00508
00510
00511
00512 inline Transform& Transform::operator=( const InverseTransform& X ) {
00513
00514
00515 T_BF = X.T();
00516 R_BF = X.R();
00517 return *this;
00518 }
00519
00520 inline Transform Transform::compose( const InverseTransform& X_FY ) const {
00521 return Transform( R_BF * X_FY.R(), T_BF + R_BF * X_FY.T() );
00522 }
00523
00524 inline Transform operator*( const Transform& X1, const Transform& X2 ) { return X1.compose(X2); }
00525 inline Transform operator*( const Transform& X1, const InverseTransform& X2 ) { return X1.compose(X2); }
00526 inline Transform operator*( const InverseTransform& X1, const Transform& X2 ) { return X1.compose(X2); }
00527 inline Transform operator*( const InverseTransform& X1, const InverseTransform& X2 ) { return X1.compose(X2); }
00528
00529 inline bool operator==( const Transform& X1, const Transform& X2 ) { return X1.R()==X2.R() && X1.T()==X2.T(); }
00530 inline bool operator==( const InverseTransform& X1, const InverseTransform& X2 ) { return X1.R()==X2.R() && X1.T()==X2.T(); }
00531 inline bool operator==( const Transform& X1, const InverseTransform& X2 ) { return X1.R()==X2.R() && X1.T()==X2.T(); }
00532 inline bool operator==( const InverseTransform& X1, const Transform& X2 ) { return X1.R()==X2.R() && X1.T()==X2.T(); }
00533
00534 SimTK_SimTKCOMMON_EXPORT std::ostream& operator<<( std::ostream& o, const Transform& );
00535
00536
00537
00538 }
00539
00540
00541 #endif // SimTK_TRANSFORM_H_
00542
00543