CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DataFormats/GeometrySurface/interface/sseTkRotation.h

Go to the documentation of this file.
00001 #ifndef Geom_newTkRotation_H
00002 #define Geom_newTkRotation_H
00003 
00004 #include "DataFormats/GeometryVector/interface/Basic2DVector.h"
00005 #include "DataFormats/GeometryVector/interface/Basic3DVector.h"
00006 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00007 
00008 #include "DataFormats/Math/interface/SSERot.h"
00009 
00010 
00011 #include <iosfwd>
00012 
00013 template <class T> class TkRotation;
00014 template <class T> class TkRotation2D;
00015 
00016 template <class T>
00017 std::ostream & operator<<( std::ostream& s, const TkRotation<T>& r);
00018 template <class T>
00019 std::ostream & operator<<( std::ostream& s, const TkRotation2D<T>& r);
00020 
00021 namespace geometryDetails {
00022   void TkRotationErr1();
00023   void TkRotationErr2();
00024 
00025 }
00026 
00027 
00031 template <class T>
00032 class TkRotation {
00033 public:
00034 
00035   typedef Vector3DBase< T, GlobalTag>  GlobalVector;
00036   typedef Basic3DVector<T> BasicVector;
00037 
00038   TkRotation( ){}
00039   TkRotation(  mathSSE::Rot3<T> const & irot ) : rot(irot){}
00040   
00041   TkRotation( T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz) :
00042     rot(xx,xy,xz, yx,yy,yz, zx, zy,zz){}
00043 
00044   TkRotation( const T* p) : 
00045     rot(p[0],p[1],p[2], 
00046         p[3],p[4],p[5],
00047         p[6],p[7],p[8]) {}
00048         
00049   TkRotation( const GlobalVector & aX, const GlobalVector & aY)  {
00050     
00051     GlobalVector uX = aX.unit();
00052     GlobalVector uY = aY.unit();
00053     GlobalVector uZ(uX.cross(uY));
00054     
00055     rot.axis[0]= uX.basicVector().v;
00056     rot.axis[1]= uY.basicVector().v;
00057     rot.axis[2]= uZ.basicVector().v;
00058     
00059   }
00060 
00061   TkRotation( const BasicVector & aX, const BasicVector & aY)  {
00062     
00063     BasicVector uX = aX.unit();
00064     BasicVector uY = aY.unit();
00065     BasicVector uZ(uX.cross(uY));
00066     
00067     rot.axis[0]= uX.v;
00068     rot.axis[1]= uY.v;
00069     rot.axis[2]= uZ.v;
00070     
00071   }
00072 
00073   
00078   TkRotation( const GlobalVector & uX, const GlobalVector & uY, 
00079               const GlobalVector & uZ) {
00080     rot.axis[0]= uX.basicVector().v;
00081     rot.axis[1]= uY.basicVector().v;
00082     rot.axis[2]= uZ.basicVector().v;
00083   }
00084 
00085   TkRotation( const BasicVector & uX, const BasicVector & uY, 
00086               const BasicVector & uZ) {
00087     rot.axis[0]= uX.v;
00088     rot.axis[1]= uY.v;
00089     rot.axis[2]= uZ.v;
00090   }
00091   
00092   
00101   TkRotation( const Basic3DVector<T>& axis, T phi) :
00102     rot(  cos(phi), sin(phi), 0, 
00103           -sin(phi), cos(phi), 0,
00104           0,        0, 1) {
00105     
00106     //rotation around the z-axis by  phi
00107     TkRotation tmpRotz ( cos(axis.phi()), sin(axis.phi()), 0.,
00108                          -sin(axis.phi()), cos(axis.phi()), 0.,
00109                          0.,              0.,              1. );
00110     //rotation around y-axis by theta
00111     TkRotation tmpRoty ( cos(axis.theta()), 0.,-sin(axis.theta()),
00112                          0.,              1.,              0.,
00113                          sin(axis.theta()), 0., cos(axis.theta()) );
00114     (*this)*=tmpRoty;
00115     (*this)*=tmpRotz;      // =  this * tmpRoty * tmpRotz 
00116     
00117     // (tmpRoty * tmpRotz)^-1 * this * tmpRoty * tmpRotz
00118     
00119     *this = (tmpRoty*tmpRotz).multiplyInverse(*this);
00120     
00121   }
00122   /* this is the same thing...derived from the CLHEP ... it gives the
00123      same results MODULO the sign of the rotation....  but I don't want
00124      that... had 
00125      TkRotation (const Basic3DVector<T>& axis, float phi) {
00126      T cx = axis.x();
00127      T cy = axis.y();
00128      T cz = axis.z();
00129      
00130      T ll = axis.mag();
00131      if (ll == 0) {
00132      geometryDetails::TkRotationErr1();
00133      }else{
00134      
00135      float cosa = cos(phi), sina = sin(phi);
00136      cx /= ll; cy /= ll; cz /= ll;   
00137      
00138      R11 = cosa + (1-cosa)*cx*cx;
00139      R12 =        (1-cosa)*cx*cy - sina*cz;
00140      R13 =        (1-cosa)*cx*cz + sina*cy;
00141      
00142      R21 =        (1-cosa)*cy*cx + sina*cz;
00143      R22 = cosa + (1-cosa)*cy*cy; 
00144      R23 =        (1-cosa)*cy*cz - sina*cx;
00145      
00146      R31 =        (1-cosa)*cz*cx - sina*cy;
00147      R32 =        (1-cosa)*cz*cy + sina*cx;
00148      R33 = cosa + (1-cosa)*cz*cz;
00149      
00150      }
00151      
00152      }
00153   */
00154   
00155   template <typename U>
00156   TkRotation( const TkRotation<U>& a) : 
00157     rot (a.xx(), a.xy(), a.xz(), 
00158          a.yx(), a.yy(), a.yz(),
00159          a.zx(), a.zy(), a.zz()) {}
00160   
00161   TkRotation transposed() const {
00162     return rot.transpose();
00163   }
00164   
00165   Basic3DVector<T> rotate( const Basic3DVector<T>& v) const {
00166     return rot.rotate(v.v);
00167   }
00168 
00169   Basic3DVector<T> rotateBack( const Basic3DVector<T>& v) const {
00170     return rot.rotateBack(v.v);
00171   }
00172 
00173 
00174   Basic3DVector<T> operator*( const Basic3DVector<T>& v) const {
00175     return rot.rotate(v.v);
00176   }
00177 
00178   Basic3DVector<T> multiplyInverse( const Basic3DVector<T>& v) const {
00179     return rot.rotateBack(v.v);
00180   }
00181   
00182   template <class Scalar>
00183   Basic3DVector<Scalar> multiplyInverse( const Basic3DVector<Scalar>& v) const {
00184     return Basic3DVector<Scalar>( xx()*v.x() + yx()*v.y() + zx()*v.z(),
00185                                   xy()*v.x() + yy()*v.y() + zy()*v.z(),
00186                                   xz()*v.x() + yz()*v.y() + zz()*v.z());
00187   }
00188   
00189   Basic3DVector<T> operator*( const Basic2DVector<T>& v) const {
00190     return Basic3DVector<T>( xx()*v.x() + xy()*v.y(),
00191                              yx()*v.x() + yy()*v.y(),
00192                              zx()*v.x() + zy()*v.y());
00193   }
00194   Basic3DVector<T> multiplyInverse( const Basic2DVector<T>& v) const {
00195     return Basic3DVector<T>( xx()*v.x() + yx()*v.y(),
00196                              xy()*v.x() + yy()*v.y(),
00197                              xz()*v.x() + yz()*v.y());
00198   }
00199   
00200   
00201   
00202   TkRotation operator*( const TkRotation& b) const {
00203     return rot*b.rot;
00204   }
00205   TkRotation multiplyInverse( const TkRotation& b) const {
00206     return rot.transpose()*b.rot;
00207   }
00208   
00209   TkRotation& operator*=( const TkRotation& b) {
00210     return *this = operator * (b);
00211   }
00212   
00213   // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
00214   TkRotation& transform(const TkRotation& b) {
00215     return *this = b.operator * (*this);
00216   }
00217   
00218   TkRotation & rotateAxes(const Basic3DVector<T>& newX,
00219                           const Basic3DVector<T>& newY,
00220                           const Basic3DVector<T>& newZ) {
00221     T del = 0.001;
00222     
00223     if (
00224         
00225         // the check for right-handedness is not needed since
00226         // we want to change the handedness when it's left in cmsim
00227         //
00228         //       fabs(newZ.x()-w.x()) > del ||
00229         //       fabs(newZ.y()-w.y()) > del ||
00230         //       fabs(newZ.z()-w.z()) > del ||
00231         fabs(newX.mag2()-1.) > del ||
00232         fabs(newY.mag2()-1.) > del || 
00233         fabs(newZ.mag2()-1.) > del ||
00234         fabs(newX.dot(newY)) > del ||
00235         fabs(newY.dot(newZ)) > del ||
00236         fabs(newZ.dot(newX)) > del) {
00237       geometryDetails::TkRotationErr2();
00238       return *this;
00239     } else {
00240       return transform(TkRotation(newX.x(), newY.x(), newZ.x(),
00241                                   newX.y(), newY.y(), newZ.y(),
00242                                   newX.z(), newY.z(), newZ.z()));
00243     }
00244   }
00245   
00246   
00247   Basic3DVector<T> x() const { return rot.axis[0];}
00248   Basic3DVector<T> y() const { return rot.axis[1];}
00249   Basic3DVector<T> z() const { return rot.axis[2];}
00250   
00251   T xx() const { return rot.axis[0].arr[0];} 
00252   T xy() const { return rot.axis[0].arr[1];} 
00253   T xz() const { return rot.axis[0].arr[2];} 
00254   T yx() const { return rot.axis[1].arr[0];} 
00255   T yy() const { return rot.axis[1].arr[1];} 
00256   T yz() const { return rot.axis[1].arr[2];} 
00257   T zx() const { return rot.axis[2].arr[0];} 
00258   T zy() const { return rot.axis[2].arr[1];} 
00259   T zz() const { return rot.axis[2].arr[2];} 
00260   
00261 private:
00262   
00263   mathSSE::Rot3<T> rot;
00264   
00265 };
00266 
00267 
00268 template<>
00269 std::ostream & operator<< <float>( std::ostream& s, const TkRotation<float>& r);
00270 
00271 template<>
00272 std::ostream & operator<< <double>( std::ostream& s, const TkRotation<double>& r);
00273 
00274 
00275 template <class T, class U>
00276 inline Basic3DVector<U> operator*( const TkRotation<T>& r, const Basic3DVector<U>& v) {
00277   return Basic3DVector<U>( r.xx()*v.x() + r.xy()*v.y() + r.xz()*v.z(),
00278                            r.yx()*v.x() + r.yy()*v.y() + r.yz()*v.z(),
00279                            r.zx()*v.x() + r.zy()*v.y() + r.zz()*v.z());
00280 }
00281 
00282 template <class T, class U>
00283 inline TkRotation<typename PreciseFloatType<T,U>::Type>
00284 operator*( const TkRotation<T>& a, const TkRotation<U>& b) {
00285     typedef TkRotation<typename PreciseFloatType<T,U>::Type> RT;
00286     return RT( a.xx()*b.xx() + a.xy()*b.yx() + a.xz()*b.zx(),
00287                a.xx()*b.xy() + a.xy()*b.yy() + a.xz()*b.zy(),
00288                a.xx()*b.xz() + a.xy()*b.yz() + a.xz()*b.zz(),
00289                a.yx()*b.xx() + a.yy()*b.yx() + a.yz()*b.zx(),
00290                a.yx()*b.xy() + a.yy()*b.yy() + a.yz()*b.zy(),
00291                a.yx()*b.xz() + a.yy()*b.yz() + a.yz()*b.zz(),
00292                a.zx()*b.xx() + a.zy()*b.yx() + a.zz()*b.zx(),
00293                a.zx()*b.xy() + a.zy()*b.yy() + a.zz()*b.zy(),
00294                a.zx()*b.xz() + a.zy()*b.yz() + a.zz()*b.zz());
00295 }
00296 
00297 
00298 template <class T>
00299 class TkRotation2D {
00300 public:
00301 
00302   typedef Basic2DVector<T> BasicVector;
00303 
00304   TkRotation2D( ){}
00305   TkRotation2D(  mathSSE::Rot2<T> const & irot ) : rot(irot){}
00306   
00307   TkRotation2D( T xx, T xy, T yx, T yy) :
00308     rot(xx,xy, yx,yy){}
00309 
00310   TkRotation2D( const T* p) : 
00311     rot(p[0],p[1],
00312         p[2],p[3]) {}
00313         
00314   TkRotation2D( const BasicVector & aX)  {
00315     
00316     BasicVector uX = aX.unit();
00317     BasicVector uY(-uX.y(),uX.x());
00318     
00319     rot.axis[0]= uX.v;
00320     rot.axis[1]= uY.v;
00321     
00322   }
00323 
00324   
00325   TkRotation2D( const BasicVector & uX, const BasicVector & uY) {
00326     rot.axis[0]= uX.v;
00327     rot.axis[1]= uY.v;
00328   }
00329   
00330   BasicVector x() const { return rot.axis[0];}
00331   BasicVector y() const { return rot.axis[1];}
00332 
00333 
00334   TkRotation2D transposed() const {
00335     return rot.transpose();
00336   }
00337   
00338   BasicVector rotate( const BasicVector& v) const {
00339     return rot.rotate(v.v);
00340   }
00341 
00342   BasicVector rotateBack( const BasicVector& v) const {
00343     return rot.rotateBack(v.v);
00344   }
00345 
00346 
00347 
00348  private:
00349   
00350   mathSSE::Rot2<T> rot;
00351  
00352 };
00353 
00354 
00355 template<>
00356 std::ostream & operator<< <float>( std::ostream& s, const TkRotation2D<float>& r);
00357 
00358 template<>
00359 std::ostream & operator<< <double>( std::ostream& s, const TkRotation2D<double>& r);
00360 
00361 
00362 #endif
00363 
00364 
00365 
00366