Transform3D.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: Transform3D.h 22516 2008-03-07 15:14:26Z moneta $
00002 // Authors: W. Brown, M. Fischler, L. Moneta    2005  
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2005 , LCG ROOT MathLib Team                         *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Header file for class Transform3D
00012 // 
00013 // Created by: Lorenzo Moneta  October 21 2005
00014 // 
00015 // 
00016 #ifndef ROOT_Math_GenVector_Transform3D 
00017 #define ROOT_Math_GenVector_Transform3D  1
00018 
00019 
00020 
00021 #ifndef ROOT_Math_GenVector_DisplacementVector3D 
00022 #include "Math/GenVector/DisplacementVector3D.h"
00023 #endif
00024 
00025 #ifndef ROOT_Math_GenVector_PositionVector3D 
00026 #include "Math/GenVector/PositionVector3D.h"
00027 #endif
00028 
00029 #ifndef ROOT_Math_GenVector_Rotation3D 
00030 #include "Math/GenVector/Rotation3D.h"
00031 #endif
00032 
00033 #ifndef ROOT_Math_GenVector_Translation3D 
00034 #include "Math/GenVector/Translation3D.h"
00035 #endif
00036 
00037 
00038 #include "Math/GenVector/AxisAnglefwd.h"
00039 #include "Math/GenVector/EulerAnglesfwd.h"
00040 #include "Math/GenVector/Quaternionfwd.h"
00041 #include "Math/GenVector/RotationZYXfwd.h"
00042 #include "Math/GenVector/RotationXfwd.h"
00043 #include "Math/GenVector/RotationYfwd.h"
00044 #include "Math/GenVector/RotationZfwd.h"
00045 
00046 #include <iostream>
00047 
00048 //#include "Math/Vector3Dfwd.h"
00049 
00050 
00051 
00052 namespace ROOT { 
00053 
00054 namespace Math { 
00055 
00056 
00057    class Plane3D; 
00058 
00059 
00060 //_________________________________________________________________________________________
00061 /** 
00062     Basic 3D Transformation class describing  a rotation and then a translation
00063     The internal data are a 3D rotation data (represented as a 3x3 matrix) and a 3D vector data. 
00064     They are represented and held in this class like a 3x4 matrix (a simple array of 12 numbers).
00065 
00066     The class can be constructed from any 3D rotation object 
00067     (ROOT::Math::Rotation3D, ROOT::Math::AxisAngle, ROOT::Math::Quaternion, etc...) and/or 
00068     a 3D Vector (ROOT::Math::DislacementVector3D or via ROOT::Math::Translation ) representing a Translation.
00069     The Transformation is defined by applying first the rotation and then the translation. 
00070     A transformation defined by applying first a translation and then a rotation is equivalent to the 
00071     transformation obtained applying first the rotation and then a translation equivalent to the rotated vector.
00072     The operator * can be used to obtain directly such transformations, in addition to combine various 
00073     transformations. 
00074     Keep in mind that the operator * (like in the case of rotations ) is not commutative. 
00075     The operator * is used (in addition to operator() ) to apply a transformations on the vector 
00076     (DisplacementVector3D and LorentzVector classes) and point (PositionVector3D)  classes. 
00077     In the case of Vector objects the transformation only rotates them and does not translate them. 
00078     Only Point objects are able to be both rotated and translated. 
00079     
00080     
00081     @ingroup GenVector
00082 
00083 */ 
00084 
00085 class Transform3D { 
00086     
00087 
00088 public: 
00089 
00090    typedef  DisplacementVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag >  Vector; 
00091    typedef  PositionVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag >      Point; 
00092 
00093 
00094    enum ETransform3DMatrixIndex {
00095       kXX = 0, kXY = 1, kXZ = 2, kDX = 3, 
00096       kYX = 4, kYY = 5, kYZ = 6, kDY = 7,
00097       kZX = 8, kZY = 9, kZZ =10, kDZ = 11
00098    };
00099 
00100 
00101 
00102    /** 
00103        Default constructor (identy rotation) + zero translation
00104    */ 
00105    Transform3D()
00106    {
00107       SetIdentity();
00108    }
00109     
00110    /**
00111       Construct given a pair of pointers or iterators defining the
00112       beginning and end of an array of 12 Scalars
00113    */
00114    template<class IT>
00115    Transform3D(IT begin, IT end) 
00116    { 
00117       SetComponents(begin,end); 
00118    }
00119 
00120    /**
00121       Construct from a rotation and then a translation described by a Vector 
00122    */
00123    Transform3D( const Rotation3D & r, const Vector & v) 
00124    {
00125       AssignFrom( r, v ); 
00126    }
00127    /**
00128       Construct from a rotation and then a translation described by a Translation3D class 
00129    */
00130    Transform3D( const Rotation3D & r, const Translation3D & t) 
00131    {
00132       AssignFrom( r, t.Vect() ); 
00133    }
00134 
00135    /**
00136       Construct from a rotation (any rotation object)  and then a translation 
00137       (represented by any DisplacementVector)
00138       The requirements on the rotation and vector objects are that they can be transformed in a 
00139       Rotation3D class and in a Cartesian3D Vector
00140    */
00141    template <class ARotation, class CoordSystem, class Tag>
00142    Transform3D( const ARotation & r, const DisplacementVector3D<CoordSystem,Tag> & v) 
00143    {
00144       AssignFrom( Rotation3D(r), Vector (v.X(),v.Y(),v.Z()) ); 
00145    }
00146 
00147    /**
00148       Construct from a rotation (any rotation object)  and then a translation 
00149       represented by a Translation3D class
00150       The requirements on the rotation is that it can be transformed in a 
00151       Rotation3D class 
00152    */
00153    template <class ARotation>
00154    Transform3D( const ARotation & r, const Translation3D & t) 
00155    {
00156       AssignFrom( Rotation3D(r), t.Vect() ); 
00157    }
00158 
00159 
00160 #ifdef OLD_VERSION
00161    /**
00162       Construct from a translation and then a rotation (inverse assignment) 
00163    */
00164    Transform3D( const Vector & v, const Rotation3D & r) 
00165    {
00166       // is equivalent from having first the rotation and then the translation vector rotated
00167       AssignFrom( r, r(v) ); 
00168    }
00169 #endif
00170 
00171    /**
00172       Construct from a 3D Rotation only with zero translation
00173    */
00174    explicit Transform3D( const Rotation3D & r) { 
00175       AssignFrom(r);
00176    } 
00177 
00178    // convenience methods for constructing a Transform3D from all the 3D rotations classes
00179    // (cannot use templates for conflict with LA)
00180 
00181    explicit Transform3D( const AxisAngle & r) { 
00182       AssignFrom(Rotation3D(r));
00183    } 
00184    explicit Transform3D( const EulerAngles & r) { 
00185       AssignFrom(Rotation3D(r));
00186    } 
00187    explicit Transform3D( const Quaternion & r) { 
00188       AssignFrom(Rotation3D(r));
00189    } 
00190    explicit Transform3D( const RotationZYX & r) { 
00191       AssignFrom(Rotation3D(r));
00192    } 
00193 
00194    // Constructors from axial rotations 
00195    // TO DO: implement direct methods for axial rotations without going through Rotation3D
00196    explicit Transform3D( const RotationX & r) { 
00197       AssignFrom(Rotation3D(r));
00198    } 
00199    explicit Transform3D( const RotationY & r) { 
00200       AssignFrom(Rotation3D(r));
00201    } 
00202    explicit Transform3D( const RotationZ & r) { 
00203       AssignFrom(Rotation3D(r));
00204    } 
00205 
00206    /**
00207       Construct from a translation only, represented by any DisplacementVector3D 
00208       and with an identity rotation
00209    */
00210    template<class CoordSystem, class Tag>
00211    explicit Transform3D( const DisplacementVector3D<CoordSystem,Tag> & v) { 
00212       AssignFrom(Vector(v.X(),v.Y(),v.Z()));
00213    }
00214    /**
00215       Construct from a translation only, represented by a Cartesian 3D Vector,  
00216       and with an identity rotation
00217    */
00218    explicit Transform3D( const Vector & v) { 
00219       AssignFrom(v);
00220    }
00221    /**
00222       Construct from a translation only, represented by a Translation3D class  
00223       and with an identity rotation
00224    */
00225    explicit Transform3D( const Translation3D & t) { 
00226       AssignFrom(t.Vect());
00227    }
00228 
00229 
00230 
00231    //#if !defined(__MAKECINT__) && !defined(G__DICTIONARY)  // this is ambigous with double * , double *   
00232 
00233 
00234 #ifdef OLD_VERSION
00235    /**
00236       Construct from a translation (using any type of DisplacementVector ) 
00237       and then a rotation (any rotation object). 
00238       Requirement on the rotation and vector objects are that they can be transformed in a 
00239       Rotation3D class and in a Vector 
00240    */
00241    template <class ARotation, class CoordSystem, class Tag>
00242    Transform3D(const DisplacementVector3D<CoordSystem,Tag> & v , const ARotation & r) 
00243    {
00244       // is equivalent from having first the rotation and then the translation vector rotated
00245       Rotation3D r3d(r);
00246       AssignFrom( r3d, r3d( Vector(v.X(),v.Y(),v.Z()) ) ); 
00247    }
00248 #endif
00249 
00250 
00251    /**
00252       Construct transformation from one coordinate system defined by three 
00253       points (origin + two axis) to 
00254       a new coordinate system defined by other three points (origin + axis) 
00255       @param fr0  point defining origin of original reference system 
00256       @param fr1  point defining first axis of original reference system 
00257       @param fr2  point defining second axis of original reference system 
00258       @param to0  point defining origin of transformed reference system 
00259       @param to1  point defining first axis transformed reference system 
00260       @param to2  point defining second axis transformed reference system 
00261 
00262    */
00263    Transform3D
00264    (const Point & fr0, const Point & fr1, const Point & fr2,  
00265     const Point & to0, const Point & to1, const Point & to2 );  
00266 
00267 
00268    // use compiler generated copy ctor, copy assignmet and dtor
00269 
00270    /**
00271       Construct from a linear algebra matrix of size at least 3x4,
00272       which must support operator()(i,j) to obtain elements (0,0) thru (2,3).
00273       The 3x3 sub-block is assumed to be the rotation part and the translations vector 
00274       are described by the 4-th column
00275    */
00276    template<class ForeignMatrix>
00277    explicit Transform3D(const ForeignMatrix & m) { 
00278       SetComponents(m); 
00279    }
00280 
00281    /**
00282       Raw constructor from 12 Scalar components
00283    */
00284    Transform3D(double  xx, double  xy, double  xz, double dx, 
00285                double  yx, double  yy, double  yz, double dy,
00286                double  zx, double  zy, double  zz, double dz)
00287    {
00288       SetComponents (xx, xy, xz, dx, yx, yy, yz, dy, zx, zy, zz, dz);
00289    }
00290 
00291 
00292    /**
00293       Construct from a linear algebra matrix of size at least 3x4,
00294       which must support operator()(i,j) to obtain elements (0,0) thru (2,3).
00295       The 3x3 sub-block is assumed to be the rotation part and the translations vector 
00296       are described by the 4-th column
00297    */
00298    template<class ForeignMatrix>
00299    Transform3D & operator= (const ForeignMatrix & m) { 
00300       SetComponents(m); 
00301       return *this; 
00302    }
00303 
00304 
00305    // ======== Components ==============
00306 
00307 
00308    /**
00309       Set the 12 matrix components given an iterator to the start of
00310       the desired data, and another to the end (12 past start).
00311    */
00312    template<class IT>
00313    void SetComponents(IT begin, IT end) {
00314       for (int i = 0; i <12; ++i) { 
00315          fM[i] = *begin;
00316          ++begin; 
00317       }
00318       assert (end==begin);
00319    }
00320 
00321    /**
00322       Get the 12 matrix components into data specified by an iterator begin
00323       and another to the end of the desired data (12 past start).
00324    */
00325    template<class IT>
00326    void GetComponents(IT begin, IT end) const {
00327       for (int i = 0; i <12; ++i) { 
00328          *begin = fM[i];
00329          ++begin;  
00330       }
00331       assert (end==begin);
00332    }
00333 
00334    /**
00335       Get the 12 matrix components into data specified by an iterator begin
00336    */
00337    template<class IT>
00338    void GetComponents(IT begin) const {
00339       std::copy ( fM, fM+12, begin );
00340    }
00341 
00342    /**
00343       Set components from a linear algebra matrix of size at least 3x4,
00344       which must support operator()(i,j) to obtain elements (0,0) thru (2,3).
00345       The 3x3 sub-block is assumed to be the rotation part and the translations vector 
00346       are described by the 4-th column
00347    */
00348    template<class ForeignMatrix>
00349    void
00350    SetTransformMatrix (const ForeignMatrix & m) {
00351       fM[kXX]=m(0,0);  fM[kXY]=m(0,1);  fM[kXZ]=m(0,2); fM[kDX]=m(0,3);
00352       fM[kYX]=m(1,0);  fM[kYY]=m(1,1);  fM[kYZ]=m(1,2); fM[kDY]=m(1,3);
00353       fM[kZX]=m(2,0);  fM[kZY]=m(2,1);  fM[kZZ]=m(2,2); fM[kDZ]=m(2,3);
00354    }
00355 
00356    /**
00357       Get components into a linear algebra matrix of size at least 3x4,
00358       which must support operator()(i,j) for write access to elements
00359       (0,0) thru (2,3).
00360    */
00361    template<class ForeignMatrix>
00362    void
00363    GetTransformMatrix (ForeignMatrix & m) const {
00364       m(0,0)=fM[kXX];  m(0,1)=fM[kXY];  m(0,2)=fM[kXZ];  m(0,3)=fM[kDX];
00365       m(1,0)=fM[kYX];  m(1,1)=fM[kYY];  m(1,2)=fM[kYZ];  m(1,3)=fM[kDY];
00366       m(2,0)=fM[kZX];  m(2,1)=fM[kZY];  m(2,2)=fM[kZZ];  m(2,3)=fM[kDZ];
00367    }
00368 
00369 
00370    /**
00371       Set the components from 12 scalars 
00372    */
00373    void
00374    SetComponents (double  xx, double  xy, double  xz, double dx,  
00375                   double  yx, double  yy, double  yz, double dy, 
00376                   double  zx, double  zy, double  zz, double dz) {
00377       fM[kXX]=xx;  fM[kXY]=xy;  fM[kXZ]=xz;  fM[kDX]=dx;
00378       fM[kYX]=yx;  fM[kYY]=yy;  fM[kYZ]=yz;  fM[kDY]=dy;
00379       fM[kZX]=zx;  fM[kZY]=zy;  fM[kZZ]=zz;  fM[kDZ]=dz;
00380    }
00381 
00382    /**
00383       Get the components into 12 scalars
00384    */
00385    void
00386    GetComponents (double &xx, double &xy, double &xz, double &dx,
00387                   double &yx, double &yy, double &yz, double &dy,
00388                   double &zx, double &zy, double &zz, double &dz) const {
00389       xx=fM[kXX];  xy=fM[kXY];  xz=fM[kXZ];  dx=fM[kDX];
00390       yx=fM[kYX];  yy=fM[kYY];  yz=fM[kYZ];  dy=fM[kDY];
00391       zx=fM[kZX];  zy=fM[kZY];  zz=fM[kZZ];  dz=fM[kDZ];
00392    }
00393 
00394 
00395    /**
00396       Get the rotation and translation vector representing the 3D transformation
00397       in any rotation and any vector (the Translation class could also be used) 
00398    */    
00399    template<class AnyRotation, class V> 
00400    void GetDecomposition(AnyRotation &r, V &v) const { 
00401       GetRotation(r);
00402       GetTranslation(v);
00403    }
00404     
00405 
00406    /**
00407       Get the rotation and translation vector representing the 3D transformation
00408    */    
00409    void GetDecomposition(Rotation3D &r, Vector &v) const { 
00410       GetRotation(r);
00411       GetTranslation(v);
00412    }
00413 
00414    /**
00415       Get the 3D rotation representing the 3D transformation
00416    */        
00417    Rotation3D Rotation() const { 
00418       return Rotation3D( fM[kXX], fM[kXY], fM[kXZ],
00419                          fM[kYX], fM[kYY], fM[kYZ],
00420                          fM[kZX], fM[kZY], fM[kZZ] );
00421    }
00422 
00423    /**
00424       Get the rotation representing the 3D transformation
00425    */        
00426    template <class AnyRotation>
00427    AnyRotation Rotation() const { 
00428       return AnyRotation(Rotation3D(fM[kXX], fM[kXY], fM[kXZ],
00429                                     fM[kYX], fM[kYY], fM[kYZ],
00430                                     fM[kZX], fM[kZY], fM[kZZ] ) ); 
00431    }
00432 
00433    /**
00434       Get the  rotation (any type) representing the 3D transformation
00435    */        
00436    template <class AnyRotation>
00437    void GetRotation(AnyRotation &r) const { 
00438       r = Rotation();
00439    }
00440 
00441    /**
00442       Get the translation representing the 3D transformation in a Cartesian vector
00443    */        
00444    Translation3D Translation() const { 
00445       return Translation3D( fM[kDX], fM[kDY], fM[kDZ] );
00446    }
00447 
00448    /**
00449       Get the translation representing the 3D transformation in any vector 
00450       which implements the SetXYZ method
00451    */        
00452    template <class AnyVector>
00453    void GetTranslation(AnyVector &v) const { 
00454       v.SetXYZ(fM[kDX], fM[kDY], fM[kDZ]); 
00455    }
00456 
00457 
00458 
00459    // operations on points and vectors 
00460 
00461    /**
00462       Transformation operation for Position Vector in Cartesian coordinate 
00463       For a Position Vector first a rotation and then a translation is applied  
00464    */
00465    Point operator() (const Point & p) const { 
00466       return Point ( fM[kXX]*p.X() + fM[kXY]*p.Y() + fM[kXZ]*p.Z() + fM[kDX], 
00467                      fM[kYX]*p.X() + fM[kYY]*p.Y() + fM[kYZ]*p.Z() + fM[kDY], 
00468                      fM[kZX]*p.X() + fM[kZY]*p.Y() + fM[kZZ]*p.Z() + fM[kDZ] );  
00469    }
00470 
00471 
00472    /**
00473       Transformation operation for Displacement Vectors in Cartesian coordinate 
00474       For the Displacement Vectors only the rotation applies - no translations
00475    */
00476    Vector operator() (const Vector & v) const { 
00477       return Vector( fM[kXX]*v.X() + fM[kXY]*v.Y() + fM[kXZ]*v.Z() , 
00478                      fM[kYX]*v.X() + fM[kYY]*v.Y() + fM[kYZ]*v.Z() , 
00479                      fM[kZX]*v.X() + fM[kZY]*v.Y() + fM[kZZ]*v.Z()  );  
00480    }
00481 
00482 
00483    /**
00484       Transformation operation for Position Vector in any coordinate system 
00485    */
00486    template<class CoordSystem > 
00487    PositionVector3D<CoordSystem> operator() (const PositionVector3D <CoordSystem> & p) const { 
00488       Point xyzNew = operator() ( Point(p) );
00489       return  PositionVector3D<CoordSystem> (xyzNew);
00490    }
00491 
00492    /**
00493       Transformation operation for Displacement Vector in any coordinate system 
00494    */
00495    template<class CoordSystem > 
00496    DisplacementVector3D<CoordSystem> operator() (const DisplacementVector3D <CoordSystem> & v) const { 
00497       Vector xyzNew = operator() ( Vector(v) );
00498       return  DisplacementVector3D<CoordSystem> (xyzNew);
00499    }
00500 
00501    /**
00502       Transformation operation for points between different coordinate system tags 
00503    */
00504    template<class CoordSystem, class Tag1, class Tag2 > 
00505    void Transform (const PositionVector3D <CoordSystem,Tag1> & p1, PositionVector3D <CoordSystem,Tag2> & p2  ) const { 
00506       Point xyzNew = operator() ( Point(p1.X(), p1.Y(), p1.Z()) );
00507       p2.SetXYZ( xyzNew.X(), xyzNew.Y(), xyzNew.Z() ); 
00508    }
00509 
00510 
00511    /**
00512       Transformation operation for Displacement Vector of different coordinate systems 
00513    */
00514    template<class CoordSystem,  class Tag1, class Tag2 > 
00515    void Transform (const DisplacementVector3D <CoordSystem,Tag1> & v1, DisplacementVector3D <CoordSystem,Tag2> & v2  ) const { 
00516       Vector xyzNew = operator() ( Vector(v1.X(), v1.Y(), v1.Z() ) );
00517       v2.SetXYZ( xyzNew.X(), xyzNew.Y(), xyzNew.Z() ); 
00518    }
00519 
00520    /**
00521       Transformation operation for a Lorentz Vector in any  coordinate system 
00522    */
00523    template <class CoordSystem > 
00524    LorentzVector<CoordSystem> operator() (const LorentzVector<CoordSystem> & q) const { 
00525       Vector xyzNew = operator() ( Vector(q.Vect() ) );
00526       return  LorentzVector<CoordSystem> (xyzNew.X(), xyzNew.Y(), xyzNew.Z(), q.E() );
00527    }
00528 
00529    /**
00530       Transformation on a 3D plane
00531    */
00532    Plane3D operator() (const Plane3D & plane) const; 
00533           
00534 
00535    // skip transformation for arbitrary vectors - not really defined if point or displacement vectors
00536 
00537    // same but with operator * 
00538    /**
00539       Transformation operation for Vectors. Apply same rules as operator() 
00540       depending on type of vector. 
00541       Will work only for DisplacementVector3D, PositionVector3D and LorentzVector
00542    */
00543    template<class AVector > 
00544    AVector operator * (const AVector & v) const { 
00545       return operator() (v);
00546    }
00547 
00548 
00549 
00550    /**
00551       multiply (combine) with another transformation in place
00552    */
00553    inline Transform3D & operator *= (const Transform3D  & t);
00554 
00555    /**
00556       multiply (combine) two transformations
00557    */ 
00558    inline Transform3D operator * (const Transform3D  & t) const; 
00559 
00560    /** 
00561        Invert the transformation in place
00562    */
00563    void Invert();
00564 
00565    /**
00566       Return the inverse of the transformation.
00567    */
00568    Transform3D Inverse() const { 
00569       Transform3D t(*this);
00570       t.Invert();
00571       return t;
00572    }
00573 
00574 
00575    /**
00576       Equality operator. Check equality for each element
00577       To do: use double tolerance
00578    */
00579    bool operator == (const Transform3D & rhs) const {
00580       if( fM[0] != rhs.fM[0] )  return false;
00581       if( fM[1] != rhs.fM[1] )  return false;
00582       if( fM[2] != rhs.fM[2] )  return false;
00583       if( fM[3] != rhs.fM[3] )  return false;
00584       if( fM[4] != rhs.fM[4] )  return false;
00585       if( fM[5] != rhs.fM[5] )  return false;
00586       if( fM[6] != rhs.fM[6] )  return false;
00587       if( fM[7] != rhs.fM[7] )  return false;
00588       if( fM[8] != rhs.fM[8] )  return false;
00589       if( fM[9] != rhs.fM[9] )  return false;
00590       if( fM[10]!= rhs.fM[10] ) return false;
00591       if( fM[11]!= rhs.fM[11] ) return false;
00592       return true;
00593    }
00594 
00595    /**
00596       Inequality operator. Check equality for each element
00597       To do: use double tolerance
00598    */
00599    bool operator != (const Transform3D & rhs) const {
00600       return ! operator==(rhs);
00601    }
00602 
00603 
00604 protected: 
00605 
00606    /**
00607       make transformation from first a rotation then a translation
00608    */
00609    void  AssignFrom( const Rotation3D & r, const Vector & v);  
00610 
00611    /**
00612       make transformation from only rotations (zero translation)
00613    */
00614    void  AssignFrom( const Rotation3D & r);  
00615 
00616    /**
00617       make transformation from only translation (identity rotations)
00618    */
00619    void  AssignFrom( const Vector & v);  
00620 
00621    /**
00622       Set identity transformation (identity rotation , zero translation)
00623    */
00624    void SetIdentity() ; 
00625 
00626 private: 
00627 
00628 
00629    double fM[12];    // transformation elements (3x4 matrix) 
00630 
00631 };
00632 
00633 
00634 
00635    
00636 // inline functions (combination of transformations) 
00637 
00638 inline Transform3D & Transform3D::operator *= (const Transform3D  & t)
00639 {
00640    // combination of transformations
00641    
00642    SetComponents(fM[kXX]*t.fM[kXX]+fM[kXY]*t.fM[kYX]+fM[kXZ]*t.fM[kZX],
00643                  fM[kXX]*t.fM[kXY]+fM[kXY]*t.fM[kYY]+fM[kXZ]*t.fM[kZY],
00644                  fM[kXX]*t.fM[kXZ]+fM[kXY]*t.fM[kYZ]+fM[kXZ]*t.fM[kZZ],
00645                  fM[kXX]*t.fM[kDX]+fM[kXY]*t.fM[kDY]+fM[kXZ]*t.fM[kDZ]+fM[kDX],
00646                  
00647                  fM[kYX]*t.fM[kXX]+fM[kYY]*t.fM[kYX]+fM[kYZ]*t.fM[kZX],
00648                  fM[kYX]*t.fM[kXY]+fM[kYY]*t.fM[kYY]+fM[kYZ]*t.fM[kZY],
00649                  fM[kYX]*t.fM[kXZ]+fM[kYY]*t.fM[kYZ]+fM[kYZ]*t.fM[kZZ],
00650                  fM[kYX]*t.fM[kDX]+fM[kYY]*t.fM[kDY]+fM[kYZ]*t.fM[kDZ]+fM[kDY],
00651                  
00652                  fM[kZX]*t.fM[kXX]+fM[kZY]*t.fM[kYX]+fM[kZZ]*t.fM[kZX],
00653                  fM[kZX]*t.fM[kXY]+fM[kZY]*t.fM[kYY]+fM[kZZ]*t.fM[kZY],
00654                  fM[kZX]*t.fM[kXZ]+fM[kZY]*t.fM[kYZ]+fM[kZZ]*t.fM[kZZ],
00655                  fM[kZX]*t.fM[kDX]+fM[kZY]*t.fM[kDY]+fM[kZZ]*t.fM[kDZ]+fM[kDZ]);
00656    
00657    return *this;
00658 }
00659 
00660 
00661 
00662 inline Transform3D Transform3D::operator * (const Transform3D  & t) const
00663 {
00664    // combination of transformations
00665    
00666    return Transform3D(fM[kXX]*t.fM[kXX]+fM[kXY]*t.fM[kYX]+fM[kXZ]*t.fM[kZX],
00667                       fM[kXX]*t.fM[kXY]+fM[kXY]*t.fM[kYY]+fM[kXZ]*t.fM[kZY],
00668                       fM[kXX]*t.fM[kXZ]+fM[kXY]*t.fM[kYZ]+fM[kXZ]*t.fM[kZZ],
00669                       fM[kXX]*t.fM[kDX]+fM[kXY]*t.fM[kDY]+fM[kXZ]*t.fM[kDZ]+fM[kDX],
00670                       
00671                       fM[kYX]*t.fM[kXX]+fM[kYY]*t.fM[kYX]+fM[kYZ]*t.fM[kZX],
00672                       fM[kYX]*t.fM[kXY]+fM[kYY]*t.fM[kYY]+fM[kYZ]*t.fM[kZY],
00673                       fM[kYX]*t.fM[kXZ]+fM[kYY]*t.fM[kYZ]+fM[kYZ]*t.fM[kZZ],
00674                       fM[kYX]*t.fM[kDX]+fM[kYY]*t.fM[kDY]+fM[kYZ]*t.fM[kDZ]+fM[kDY],
00675                       
00676                       fM[kZX]*t.fM[kXX]+fM[kZY]*t.fM[kYX]+fM[kZZ]*t.fM[kZX],
00677                       fM[kZX]*t.fM[kXY]+fM[kZY]*t.fM[kYY]+fM[kZZ]*t.fM[kZY],
00678                       fM[kZX]*t.fM[kXZ]+fM[kZY]*t.fM[kYZ]+fM[kZZ]*t.fM[kZZ],
00679                       fM[kZX]*t.fM[kDX]+fM[kZY]*t.fM[kDY]+fM[kZZ]*t.fM[kDZ]+fM[kDZ]  );
00680    
00681 }
00682 
00683 
00684 
00685 
00686 //--- global functions resulting in Transform3D -------
00687       
00688       
00689 // ------ combination of a  translation (first)  and a rotation ------
00690 
00691 
00692 /**
00693    combine a translation and a rotation to give a transform3d
00694    First the translation then the rotation
00695  */
00696 inline Transform3D operator * (const Rotation3D & r, const Translation3D & t) { 
00697    return Transform3D( r, r(t.Vect()) );
00698 }
00699 inline Transform3D operator * (const RotationX & r, const Translation3D & t) { 
00700    Rotation3D r3(r);
00701    return Transform3D( r3, r3(t.Vect()) );
00702 }
00703 inline Transform3D operator * (const RotationY & r, const Translation3D & t) { 
00704    Rotation3D r3(r);
00705    return Transform3D( r3, r3(t.Vect()) );
00706 }
00707 inline Transform3D operator * (const RotationZ & r, const Translation3D & t) { 
00708    Rotation3D r3(r);
00709    return Transform3D( r3, r3(t.Vect()) );
00710 }
00711 inline Transform3D operator * (const RotationZYX & r, const Translation3D & t) { 
00712    Rotation3D r3(r);
00713    return Transform3D( r3, r3(t.Vect()) );
00714 }
00715 inline Transform3D operator * (const AxisAngle & r, const Translation3D & t) { 
00716    Rotation3D r3(r);
00717    return Transform3D( r3, r3(t.Vect()) );
00718 }
00719 inline Transform3D operator * (const EulerAngles & r, const Translation3D & t) { 
00720    Rotation3D r3(r);
00721    return Transform3D( r3, r3(t.Vect()) );
00722 }
00723 inline Transform3D operator * (const Quaternion & r, const Translation3D & t) { 
00724    Rotation3D r3(r);
00725    return Transform3D( r3, r3(t.Vect()) );
00726 }
00727 
00728 // ------ combination of a  rotation (first)  and then a translation ------
00729 
00730 /**
00731    combine a rotation and a translation to give a transform3d
00732    First a rotation then the translation
00733  */
00734 inline Transform3D operator * (const Translation3D & t, const Rotation3D & r) { 
00735    return Transform3D( r, t.Vect());
00736 }
00737 inline Transform3D operator * (const Translation3D & t, const RotationX & r) { 
00738    return Transform3D( Rotation3D(r) , t.Vect());
00739 }
00740 inline Transform3D operator * (const Translation3D & t, const RotationY & r) { 
00741    return Transform3D( Rotation3D(r) , t.Vect());
00742 }
00743 inline Transform3D operator * (const Translation3D & t, const RotationZ & r) { 
00744    return Transform3D( Rotation3D(r) , t.Vect());
00745 }
00746 inline Transform3D operator * (const Translation3D & t, const RotationZYX & r) { 
00747    return Transform3D( Rotation3D(r) , t.Vect());
00748 }
00749 inline Transform3D operator * (const Translation3D & t, const EulerAngles & r) { 
00750    return Transform3D( Rotation3D(r) , t.Vect());
00751 }
00752 inline Transform3D operator * (const Translation3D & t, const Quaternion & r) { 
00753    return Transform3D( Rotation3D(r) , t.Vect());
00754 }
00755 inline Transform3D operator * (const Translation3D & t, const AxisAngle & r) { 
00756    return Transform3D( Rotation3D(r) , t.Vect());
00757 }
00758 
00759 // ------ combination of a Transform3D and a pure translation------
00760 
00761 /**
00762    combine a transformation and a translation to give a transform3d
00763    First the translation then the transform3D
00764  */
00765 inline Transform3D operator * (const Transform3D & t, const Translation3D & d) { 
00766    Rotation3D r = t.Rotation();
00767    return Transform3D( r, r( d.Vect() ) + t.Translation().Vect()  );
00768 }
00769 
00770 /**
00771    combine a translation and a transformation to give a transform3d
00772    First the transformation then the translation
00773  */
00774 inline Transform3D operator * (const Translation3D & d, const Transform3D & t) { 
00775    return Transform3D( t.Rotation(), t.Translation().Vect() + d.Vect());
00776 }
00777 
00778 // ------ combination of a Transform3D and any rotation------
00779 
00780 
00781 /**
00782    combine a transformation and a rotation to give a transform3d
00783    First the rotation then the transform3D
00784  */
00785 inline Transform3D operator * (const Transform3D & t, const Rotation3D & r) { 
00786    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00787 }
00788 inline Transform3D operator * (const Transform3D & t, const RotationX & r) { 
00789    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00790 }
00791 inline Transform3D operator * (const Transform3D & t, const RotationY & r) { 
00792    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00793 }
00794 inline Transform3D operator * (const Transform3D & t, const RotationZ & r) { 
00795    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00796 }
00797 inline Transform3D operator * (const Transform3D & t, const RotationZYX & r) { 
00798    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00799 }
00800 inline Transform3D operator * (const Transform3D & t, const EulerAngles & r) { 
00801    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00802 }
00803 inline Transform3D operator * (const Transform3D & t, const AxisAngle & r) { 
00804    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00805 }
00806 inline Transform3D operator * (const Transform3D & t, const Quaternion & r) { 
00807    return Transform3D( t.Rotation()*r ,  t.Translation()  );
00808 }
00809 
00810 
00811 
00812 /**
00813    combine a rotation and a transformation to give a transform3d
00814    First the transformation then the rotation
00815  */
00816 inline Transform3D operator * (const Rotation3D & r, const Transform3D & t) { 
00817    return Transform3D( r * t.Rotation(), r * t.Translation().Vect() );
00818 }
00819 inline Transform3D operator * (const RotationX & r, const Transform3D & t) { 
00820    Rotation3D r3d(r);
00821    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00822 }
00823 inline Transform3D operator * (const RotationY & r, const Transform3D & t) { 
00824    Rotation3D r3d(r);
00825    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00826 }
00827 inline Transform3D operator * (const RotationZ & r, const Transform3D & t) { 
00828    Rotation3D r3d(r);
00829    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00830 }
00831 inline Transform3D operator * (const RotationZYX & r, const Transform3D & t) { 
00832    Rotation3D r3d(r);
00833    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00834 }
00835 inline Transform3D operator * (const EulerAngles & r, const Transform3D & t) { 
00836    Rotation3D r3d(r);
00837    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00838 }
00839 inline Transform3D operator * (const AxisAngle & r, const Transform3D & t) { 
00840    Rotation3D r3d(r);
00841    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00842 }
00843 inline Transform3D operator * (const Quaternion & r, const Transform3D & t) { 
00844    Rotation3D r3d(r);
00845    return Transform3D( r3d * t.Rotation(), r3d * t.Translation().Vect() );
00846 }
00847 
00848 
00849 //---I/O functions
00850 // TODO - I/O should be put in the manipulator form 
00851 
00852 /**
00853    print the 12 components of the Transform3D
00854  */
00855 std::ostream & operator<< (std::ostream & os, const Transform3D & t);
00856 
00857 
00858    } // end namespace Math
00859 
00860 } // end namespace ROOT
00861 
00862 
00863 #endif /* ROOT_Math_GenVector_Transform3D */

Generated on Tue Jul 5 14:25:23 2011 for ROOT_528-00b_version by  doxygen 1.5.1