LorentzRotationD.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 // ---------------------------------------------------------------------------
00003 //
00004 // This file is a part of the CLHEP - a Class Library for High Energy Physics.
00005 //
00006 // This is the implementation of those parts of the HepLorentzRotation class
00007 // which involve decomposition into Boost*Rotation.
00008 
00009 #ifdef GNUPRAGMA
00010 #pragma implementation
00011 #endif
00012 
00013 #include "CLHEP/Vector/LorentzRotation.h"
00014 
00015 namespace CLHEP  {
00016 
00017 // ----------  Decomposition:
00018 
00019 void HepLorentzRotation::decompose 
00020         (HepBoost & bboost, HepRotation & rotation) const {
00021 
00022   // The boost will be the pure boost based on column 4 of the transformation
00023   // matrix.  Since the constructor takes the beta vector, and not beta*gamma,
00024   // we first divide through by gamma = the tt element.  This of course can
00025   // never be zero since the last row has t**2 - v**2 = +1.
00026 
00027   Hep3Vector betaVec ( xt(), yt(), zt() );
00028   betaVec *= 1.0 / tt();
00029   bboost.set( betaVec );
00030 
00031   // The rotation will be inverse of B times T.
00032 
00033   HepBoost B( -betaVec );
00034   HepLorentzRotation R( B * *this );
00035 
00036   HepRep3x3 m1  ( R.xx(), R.xy(), R.xz(),
00037                   R.yx(), R.yy(), R.yz(),
00038                   R.zx(), R.zy(), R.zz() );
00039   rotation.set( m1 );
00040   rotation.rectify();
00041   
00042   return;
00043 
00044 }
00045 
00046 void HepLorentzRotation::decompose 
00047         (Hep3Vector & bboost, HepAxisAngle & rotation) const {
00048   HepRotation r;
00049   HepBoost b;
00050   decompose(b,r);
00051   bboost = b.boostVector();
00052   rotation = r.axisAngle();
00053   return;
00054 }
00055 
00056 void HepLorentzRotation::decompose 
00057         (HepRotation & rotation, HepBoost & bboost) const {
00058 
00059   // In this case the pure boost is based on row 4 of the matrix.  
00060 
00061   Hep3Vector betaVec( tx(), ty(), tz() );
00062   betaVec *= 1.0 / tt();
00063   bboost.set( betaVec );
00064 
00065   // The rotation will be T times the inverse of B.
00066 
00067   HepBoost B( -betaVec );
00068   HepLorentzRotation R( *this * B );
00069 
00070   HepRep3x3 m1 ( R.xx(), R.xy(), R.xz(),
00071                  R.yx(), R.yy(), R.yz(),
00072                  R.zx(), R.zy(), R.zz() );
00073   rotation.set( m1 );
00074   rotation.rectify();
00075   return;
00076 
00077 }
00078 
00079 void HepLorentzRotation::decompose 
00080         (HepAxisAngle & rotation, Hep3Vector & bboost) const {
00081   HepRotation r;
00082   HepBoost b;
00083   decompose(r,b);
00084   rotation = r.axisAngle();
00085   bboost = b.boostVector();
00086   return;
00087 }
00088 
00089 double HepLorentzRotation::distance2( const HepBoost & b ) const {
00090   HepBoost    b1;
00091   HepRotation r1; 
00092   decompose( b1, r1 );
00093   double db2 = b1.distance2( b );
00094   double dr2 = r1.norm2(); 
00095   return ( db2 + dr2 );
00096 }
00097 
00098 double HepLorentzRotation::distance2( const HepRotation & r ) const {
00099   HepBoost    b1;
00100   HepRotation r1; 
00101   decompose( b1, r1 );
00102   double db2 = b1.norm2( );
00103   double dr2 = r1.distance2( r ); 
00104   return ( db2 + dr2 );
00105 }
00106 
00107 double HepLorentzRotation::distance2( 
00108                                    const HepLorentzRotation & lt  ) const {
00109   HepBoost    b1;
00110   HepRotation r1; 
00111   decompose( b1, r1 );
00112   HepBoost    b2;
00113   HepRotation r2; 
00114   lt.decompose (b2, r2);
00115   double db2 = b1.distance2( b2 );
00116   double dr2 = r1.distance2( r2 ); 
00117   return ( db2 + dr2 );
00118 }
00119 
00120 double HepLorentzRotation::howNear( const HepBoost & b ) const {
00121   return std::sqrt( distance2( b ) );
00122 }
00123 double HepLorentzRotation::howNear( const HepRotation & r ) const {
00124   return std::sqrt( distance2( r ) );
00125 }
00126 double HepLorentzRotation::howNear( const HepLorentzRotation & lt )const {
00127   return std::sqrt( distance2( lt ) );
00128 }
00129 
00130 bool HepLorentzRotation::isNear(
00131                 const HepBoost & b, double epsilon ) const {
00132   HepBoost    b1;
00133   HepRotation r1; 
00134   decompose( b1, r1 );
00135   double db2 = b1.distance2(b);
00136   if ( db2 > epsilon*epsilon ) {
00137      return false;       // Saves the time-consuming Rotation::norm2
00138   }
00139   double dr2 = r1.norm2();
00140   return ( (db2 + dr2) <= epsilon*epsilon );
00141 }
00142 
00143 bool HepLorentzRotation::isNear(
00144                 const HepRotation & r, double epsilon ) const {
00145   HepBoost    b1;
00146   HepRotation r1; 
00147   decompose( b1, r1 );
00148   double db2 = b1.norm2();
00149   if ( db2 > epsilon*epsilon ) {
00150      return false;       // Saves the time-consuming Rotation::distance2
00151   }
00152   double dr2 = r1.distance2(r);
00153   return ( (db2 + dr2) <= epsilon*epsilon );
00154 }
00155 
00156 bool HepLorentzRotation::isNear(
00157                 const HepLorentzRotation & lt, double epsilon ) const {
00158   HepBoost    b1;
00159   HepRotation r1; 
00160   decompose( b1, r1 );
00161   HepBoost    b2;
00162   HepRotation r2; 
00163   lt.decompose (b2, r2);
00164   double db2 = b1.distance2(b2);
00165   if ( db2 > epsilon*epsilon ) {
00166      return false;       // Saves the time-consuming Rotation::distance2
00167   }
00168   double dr2 = r1.distance2(r2);
00169   return ( (db2 + dr2) <= epsilon*epsilon );
00170 }
00171 
00172 double HepLorentzRotation::norm2() const {
00173   HepBoost    b;
00174   HepRotation r;
00175   decompose( b, r );
00176   return b.norm2() + r.norm2();
00177 }
00178 
00179 void HepLorentzRotation::rectify() {
00180   
00181   // Assuming the representation of this is close to a true LT,
00182   // but may have drifted due to round-off error from many operations,
00183   // this forms an "exact" orthosymplectic matrix for the LT again.
00184  
00185   // There are several ways to do this, all equivalent to lowest order in
00186   // the corrected error.  We choose to form an LT based on the inverse boost
00187   // extracted from row 4, and left-multiply by LT to form what would be
00188   // a rotation if the LT were kosher.  We drop the possibly non-zero t
00189   // components of that, rectify that rotation and multiply back by the boost.
00190                     
00191   Hep3Vector beta (tx(), ty(), tz());
00192   double gam = tt();                    // NaN-proofing
00193   if ( gam <= 0 ) {
00194     std::cerr << "HepLorentzRotation::rectify() - "
00195         << "rectify() on a transformation with tt() <= 0 - will not help!"
00196         << std::endl;
00197     gam = 1;
00198   }
00199   beta *= 1.0/gam;
00200   HepLorentzRotation R = (*this) * HepBoost(-beta);
00201 
00202   HepRep3x3  m1 ( R.xx(), R.xy(), R.xz(),
00203                   R.yx(), R.yy(), R.yz(),
00204                   R.zx(), R.zy(), R.zz() );
00205 
00206   HepRotation Rgood (m1);
00207   Rgood.rectify();
00208 
00209   set ( Rgood, HepBoost(beta) );
00210 }
00211 
00212 }  // namespace CLHEP

Generated on Mon May 27 17:50:31 2013 for Geant4 by  doxygen 1.4.7