CLHEP/Vector/Rotation.h

00001 // -*- C++ -*-
00002 // CLASSDOC OFF
00003 // $Id: Rotation.h,v 1.17 2003/10/10 19:25:36 mf Exp $
00004 // ---------------------------------------------------------------------------
00005 // CLASSDOC ON
00006 //
00007 // This file is a part of the CLHEP - a Class Library for High Energy Physics.
00008 //
00009 // This is the definition of the HepRotation class for performing rotations
00010 // on objects of the Hep3Vector (and HepLorentzVector) class.
00011 //
00012 // HepRotation is a concrete implementation of Hep3RotationInterface.
00013 //
00014 // .SS See Also
00015 // RotationInterfaces.h
00016 // ThreeVector.h, LorentzVector.h, LorentzRotation.h
00017 //
00018 // .SS Author
00019 // Leif Lonnblad, Mark Fischler
00020 
00021 #ifndef HEP_ROTATION_H
00022 #define HEP_ROTATION_H
00023 
00024 #ifdef GNUPRAGMA
00025 #pragma interface
00026 #endif
00027 
00028 #include "CLHEP/Vector/RotationInterfaces.h"
00029 #include "CLHEP/Vector/RotationX.h"
00030 #include "CLHEP/Vector/RotationY.h"
00031 #include "CLHEP/Vector/RotationZ.h"
00032 #include "CLHEP/Vector/LorentzVector.h"
00033 
00034 #ifdef HEP_NO_INLINE_IN_DECLARATION
00035 #define inline
00036 #endif
00037 
00038 // Declarations of classes and global methods
00039 class HepRotation;
00040 inline HepRotation inverseOf ( const HepRotation & r );
00041 inline HepRotation operator * (const HepRotationX & rx, const HepRotation & r);
00042 inline HepRotation operator * (const HepRotationY & ry, const HepRotation & r);
00043 inline HepRotation operator * (const HepRotationZ & rz, const HepRotation & r);
00044 
00049 class HepRotation {
00050 
00051 public:
00052 
00053   // ----------  Constructors and Assignment:
00054 
00055   inline HepRotation();
00056   // Default constructor. Gives a unit matrix.
00057 
00058   inline HepRotation(const HepRotation  & m);
00059   // Copy constructor.
00060 
00061   inline HepRotation(const HepRotationX & m);
00062   inline HepRotation(const HepRotationY & m);
00063   inline HepRotation(const HepRotationZ & m);
00064   // Construct from specialized rotation.
00065 
00066   HepRotation & set( const Hep3Vector & axis, double delta );
00067   HepRotation      ( const Hep3Vector & axis, double delta );
00068   // Construct from axis and angle.
00069 
00070   HepRotation & set( const HepAxisAngle & ax );
00071   HepRotation      ( const HepAxisAngle & ax );
00072   // Construct from AxisAngle structure.
00073 
00074   HepRotation & set( double phi, double theta, double psi );
00075   HepRotation      ( double phi, double theta, double psi );
00076   // Construct from three Euler angles (in radians).
00077 
00078   HepRotation & set( const HepEulerAngles & e );
00079   HepRotation      ( const HepEulerAngles & e );
00080   // Construct from EulerAngles structure.
00081 
00082   HepRotation ( const Hep3Vector & colX,
00083                 const Hep3Vector & colY,
00084                 const Hep3Vector & colZ );
00085   // Construct from three *orthogonal* unit vector columns.
00086         // NOTE:        
00087         //       This constructor, and the two set methods below, 
00088         //       will check that the columns (or rows) form an orthonormal 
00089         //       matrix, and will adjust values so that this relation is 
00090         //       as exact as possible.
00091 
00092   HepRotation & set( const Hep3Vector & colX,
00093                              const Hep3Vector & colY,
00094                              const Hep3Vector & colZ );
00095   //   supply three *orthogonal* unit vectors for the columns.
00096 
00097   HepRotation & setRows( const Hep3Vector & rowX,
00098                                  const Hep3Vector & rowY,
00099                                  const Hep3Vector & rowZ );
00100   //   supply three *orthogonal* unit vectors for the rows.
00101 
00102   inline HepRotation & set(const HepRotationX & r);
00103   inline HepRotation & set(const HepRotationY & r);
00104   inline HepRotation & set(const HepRotationZ & r);
00105   // set from specialized rotation.
00106 
00107   inline  HepRotation & operator = (const HepRotation & r);
00108   // Assignment.
00109 
00110   inline  HepRotation & operator = (const HepRotationX & r);
00111   inline  HepRotation & operator = (const HepRotationY & r);
00112   inline  HepRotation & operator = (const HepRotationZ & r);
00113   // Assignment from specialized rotation.
00114 
00115   inline HepRotation &set( const HepRep3x3 & m );
00116   inline HepRotation     ( const HepRep3x3 & m );
00117   // WARNING - NO CHECKING IS DONE!
00118   // Constructon directly from from a 3x3 representation,
00119   // which is required to be an orthogonal matrix.
00120 
00121   inline ~HepRotation();
00122   // Trivial destructor.
00123 
00124   // ----------  Accessors:
00125 
00126   inline Hep3Vector colX() const;
00127   inline Hep3Vector colY() const;
00128   inline Hep3Vector colZ() const;
00129   // orthogonal unit-length column vectors
00130 
00131   inline Hep3Vector rowX() const;
00132   inline Hep3Vector rowY() const;
00133   inline Hep3Vector rowZ() const;
00134   // orthogonal unit-length row vectors
00135                                 
00136   inline double xx() const;
00137   inline double xy() const;
00138   inline double xz() const;
00139   inline double yx() const;
00140   inline double yy() const;
00141   inline double yz() const;
00142   inline double zx() const;
00143   inline double zy() const;
00144   inline double zz() const;
00145   // Elements of the rotation matrix (Geant4).
00146 
00147   inline HepRep3x3 rep3x3() const;
00148   //   3x3 representation:
00149 
00150   // ------------  Subscripting:
00151 
00152   class HepRotation_row {
00153   public:
00154     inline HepRotation_row(const HepRotation &, int);
00155     inline double operator [] (int) const;
00156   private:
00157     const HepRotation & rr;
00158     int ii;
00159   };
00160   // Helper class for implemention of C-style subscripting r[i][j] 
00161 
00162   inline const HepRotation_row operator [] (int) const; 
00163   // Returns object of the helper class for C-style subscripting r[i][j]
00164   // i and j range from 0 to 2.  
00165 
00166   double operator () (int, int) const;
00167   // Fortran-style subscripting: returns (i,j) element of the rotation matrix.
00168   // Note:  i and j still range from 0 to 2.                    [Rotation.cc]
00169 
00170   // ------------  Euler angles:
00171   inline  double getPhi  () const;
00172   inline  double getTheta() const;
00173   inline  double getPsi  () const;
00174   double    phi  () const;
00175   double    theta() const;
00176   double    psi  () const;
00177   HepEulerAngles eulerAngles() const;
00178 
00179   // ------------  axis & angle of rotation:
00180   inline  double  getDelta() const;
00181   inline  Hep3Vector getAxis () const;
00182   double     delta() const;
00183   Hep3Vector    axis () const;
00184   HepAxisAngle  axisAngle() const;
00185   void getAngleAxis(double & delta, Hep3Vector & axis) const;
00186   // Returns the rotation angle and rotation axis (Geant4).     [Rotation.cc]
00187 
00188   // ------------- Angles of rotated axes
00189   double phiX() const;
00190   double phiY() const;
00191   double phiZ() const;
00192   double thetaX() const;
00193   double thetaY() const;
00194   double thetaZ() const;
00195   // Return angles (RADS) made by rotated axes against original axes (Geant4).
00196   //                                                            [Rotation.cc]
00197 
00198   // ----------  Other accessors treating pure rotation as a 4-rotation
00199 
00200   inline HepLorentzVector col1() const;
00201   inline HepLorentzVector col2() const;
00202   inline HepLorentzVector col3() const;
00203   //  orthosymplectic 4-vector columns - T component will be zero
00204 
00205   inline HepLorentzVector col4() const;
00206   // Will be (0,0,0,1) for this pure Rotation.
00207 
00208   inline HepLorentzVector row1() const;
00209   inline HepLorentzVector row2() const;
00210   inline HepLorentzVector row3() const;
00211   //  orthosymplectic 4-vector rows - T component will be zero
00212 
00213   inline HepLorentzVector row4() const;
00214   // Will be (0,0,0,1) for this pure Rotation.
00215 
00216   inline double xt() const;
00217   inline double yt() const;
00218   inline double zt() const;
00219   inline double tx() const;
00220   inline double ty() const;
00221   inline double tz() const;
00222   // Will be zero for this pure Rotation
00223 
00224   inline double tt() const;
00225   // Will be one for this pure Rotation
00226 
00227   inline HepRep4x4 rep4x4() const;
00228   //   4x4 representation.
00229 
00230   // ---------   Mutators 
00231 
00232   void setPhi (double phi);
00233   // change Euler angle phi, leaving theta and psi unchanged.
00234 
00235   void setTheta (double theta);
00236   // change Euler angle theta, leaving phi and psi unchanged.
00237 
00238   void setPsi (double psi);
00239   // change Euler angle psi, leaving theta and phi unchanged.
00240 
00241   void setAxis (const Hep3Vector & axis);
00242   // change rotation axis, leaving delta unchanged.
00243 
00244   void setDelta (double delta);
00245   // change angle of rotation, leaving rotation axis unchanged.
00246 
00247   // ----------  Decomposition:
00248 
00249   void decompose (HepAxisAngle & rotation, Hep3Vector & boost) const;
00250   void decompose (Hep3Vector & boost, HepAxisAngle & rotation) const;
00251   // These are trivial, as the boost vector is 0.               [RotationP.cc]
00252 
00253   // ----------  Comparisons: 
00254   
00255   bool isIdentity() const;                              
00256   // Returns true if the identity matrix (Geant4).              [Rotation.cc]   
00257 
00258   int compare( const HepRotation & r  ) const;
00259   // Dictionary-order comparison, in order zz, zy, zx, yz, ... xx
00260   // Used in operator<, >, <=, >= 
00261 
00262   inline bool operator== ( const HepRotation & r ) const;
00263   inline bool operator!= ( const HepRotation & r ) const;
00264   inline bool operator<  ( const HepRotation & r ) const;
00265   inline bool operator>  ( const HepRotation & r ) const;
00266   inline bool operator<= ( const HepRotation & r ) const;
00267   inline bool operator>= ( const HepRotation & r ) const;
00268   
00269   double distance2( const HepRotation &  r  ) const; 
00270   // 3 - Tr ( this/r ) -- This works with RotationX, Y or Z also
00271 
00272   double howNear( const HepRotation & r ) const;
00273   bool isNear( const HepRotation & r,
00274              double epsilon=Hep4RotationInterface::tolerance) const;
00275 
00276   double distance2( const HepBoost           & lt  ) const; 
00277   // 3 - Tr ( this ) + |b|^2 / (1-|b|^2) 
00278   double distance2( const HepLorentzRotation & lt  ) const; 
00279   // 3 - Tr ( this/r ) + |b|^2 / (1-|b|^2) where b is the boost vector of lt
00280 
00281   double howNear( const HepBoost           & lt ) const;
00282   double howNear( const HepLorentzRotation & lt ) const;
00283   bool isNear( const HepBoost           & lt, 
00284              double epsilon=Hep4RotationInterface::tolerance) const;
00285   bool isNear( const HepLorentzRotation & lt,
00286              double epsilon=Hep4RotationInterface::tolerance) const;
00287 
00288   // ----------  Properties:
00289 
00290   double norm2() const; 
00291   // distance2 (IDENTITY), which is 3 - Tr ( *this )
00292 
00293   void rectify();
00294   // non-const but logically moot correction for accumulated roundoff errors
00295         // rectify averages the matrix with the transpose of its actual
00296         // inverse (absent accumulated roundoff errors, the transpose IS
00297         // the inverse)); this removes to first order those errors.
00298         // Then it formally extracts axis and delta, and forms a true
00299         // HepRotation with those values of axis and delta.
00300 
00301   // ---------- Application:
00302 
00303   inline Hep3Vector operator() (const Hep3Vector & p) const;
00304   // Rotate a Hep3Vector.                                       
00305 
00306   inline  Hep3Vector operator * (const Hep3Vector & p) const;
00307   // Multiplication with a Hep3Vector.
00308 
00309   inline HepLorentzVector operator()( const HepLorentzVector & w ) const;
00310   // Rotate (the space part of) a HepLorentzVector.             
00311 
00312   inline  HepLorentzVector operator* ( const HepLorentzVector & w ) const;
00313   // Multiplication with a HepLorentzVector.
00314 
00315   // ---------- Operations in the group of Rotations
00316 
00317   inline HepRotation operator * (const HepRotation & r) const;
00318   // Product of two rotations (this) * r - matrix multiplication  
00319 
00320   inline HepRotation operator * (const HepRotationX & rx) const; 
00321   inline HepRotation operator * (const HepRotationY & ry) const;
00322   inline HepRotation operator * (const HepRotationZ & rz) const;
00323   // Product of two rotations (this) * r - faster when specialized type 
00324 
00325   inline  HepRotation & operator *= (const HepRotation & r);
00326   inline  HepRotation & transform   (const HepRotation & r);
00327   // Matrix multiplication.
00328   // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
00329 
00330   inline  HepRotation & operator *= (const HepRotationX & r);
00331   inline  HepRotation & operator *= (const HepRotationY & r);
00332   inline  HepRotation & operator *= (const HepRotationZ & r);
00333   inline  HepRotation & transform   (const HepRotationX & r);
00334   inline  HepRotation & transform   (const HepRotationY & r);
00335   inline  HepRotation & transform   (const HepRotationZ & r);
00336   // Matrix multiplication by specialized matrices
00337 
00338   HepRotation & rotateX(double delta);
00339   // Rotation around the x-axis; equivalent to R = RotationX(delta) * R
00340 
00341   HepRotation & rotateY(double delta);
00342   // Rotation around the y-axis; equivalent to R = RotationY(delta) * R
00343 
00344   HepRotation & rotateZ(double delta);
00345   // Rotation around the z-axis; equivalent to R = RotationZ(delta) * R
00346 
00347          HepRotation & rotate(double delta, const Hep3Vector & axis);
00348   inline HepRotation & rotate(double delta, const Hep3Vector * axis);
00349   // Rotation around a specified vector.  
00350   // r.rotate(d,a) is equivalent to r = Rotation(d,a) * r
00351 
00352   HepRotation & rotateAxes(const Hep3Vector & newX,
00353                            const Hep3Vector & newY,
00354                            const Hep3Vector & newZ);
00355   // Rotation of local axes defined by 3 orthonormal vectors (Geant4).
00356   // Equivalent to r = Rotation (newX, newY, newZ) * r
00357 
00358   inline HepRotation inverse() const;
00359   // Returns the inverse.
00360 
00361   inline HepRotation & invert();
00362   // Inverts the Rotation matrix.
00363 
00364   // ---------- I/O: 
00365 
00366   HepStd::ostream & print( HepStd::ostream & os ) const;
00367   // Aligned six-digit-accurate output of the  rotation matrix. [RotationIO.cc]
00368 
00369   // ---------- Identity Rotation:
00370 
00371   static const HepRotation IDENTITY;
00372 
00373   // ---------- Tolerance
00374 
00375   static inline double getTolerance();
00376   static inline double setTolerance(double tol); 
00377 
00378 protected:
00379 
00380   inline HepRotation(double mxx, double mxy, double mxz, 
00381                      double myx, double myy, double myz,
00382                      double mzx, double mzy, double mzz);
00383   // Protected constructor.  
00384   // DOES NOT CHECK FOR VALIDITY AS A ROTATION.
00385 
00386   friend HepRotation operator* (const HepRotationX & rx, const HepRotation & r);
00387   friend HepRotation operator* (const HepRotationY & ry, const HepRotation & r);
00388   friend HepRotation operator* (const HepRotationZ & rz, const HepRotation & r);
00389 
00390   double rxx, rxy, rxz, 
00391             ryx, ryy, ryz, 
00392             rzx, rzy, rzz;
00393   // The matrix elements.
00394 
00395 private:
00396   bool 
00397        setCols ( const Hep3Vector & u1, // Vectors assume to be of unit length 
00398                  const Hep3Vector & u2,
00399                  const Hep3Vector & u3,
00400                  double u1u2,
00401                  Hep3Vector & v1,               // Returned vectors
00402                  Hep3Vector & v2,
00403                  Hep3Vector & v3 ) const;
00404   void setArbitrarily (const Hep3Vector & colX, // assumed to be of unit length
00405                       Hep3Vector & v1,
00406                       Hep3Vector & v2,
00407                       Hep3Vector & v3) const;
00408 };
00409 
00410 inline   
00411 HepStd::ostream & operator << 
00412         ( HepStd::ostream & os, const HepRotation & r ) {return r.print(os);}
00413 
00414 #
00415 #ifdef HEP_NO_INLINE_IN_DECLARATION
00416 #undef inline
00417 #endif
00418 
00419 #ifdef HEP_SHORT_NAMES
00420 typedef HepRotation Rotation;
00421 #endif
00422 
00423 #ifndef HEP_DEBUG_INLINE
00424 #include "CLHEP/Vector/Rotation.icc"
00425 #endif
00426 
00427 #endif /* HEP_ROTATION_H */
00428 

Class Library for High Energy Physics (version 1.8)