CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DataFormats/GeometrySurface/interface/newTkRotation.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 
00015 template <class T>
00016 std::ostream & operator<<( std::ostream& s, const TkRotation<T>& r);
00017 
00018 namespace geometryDetails {
00019   void TkRotationErr1();
00020   void TkRotationErr2();
00021 
00022 }
00023 
00024 
00028 template <class T>
00029 class TkRotation {
00030 public:
00031 
00032   typedef Vector3DBase< T, GlobalTag>  GlobalVector;
00033 
00034   TkRotation( ){}
00035   TkRotation(  mathSSE::Rot3<T> const & irot ) : rot(irot){}
00036   
00037   TkRotation( T xx, T xy, T xz, T yx, T yy, T yz, T zx, T zy, T zz) :
00038     rot(xx,xy,xz, yx,yy,yz, zx, zy,zz){}
00039 
00040   TkRotation( const T* p) : 
00041     rot(p[0],p[1],p[2], 
00042         p[3],p[4],p[5],
00043         p[6],p[7],p[8]) {}
00044         
00045   TkRotation( const GlobalVector & aX, const GlobalVector & aY)  {
00046     
00047     GlobalVector uX = aX.unit();
00048     GlobalVector uY = aY.unit();
00049     GlobalVector uZ(uX.cross(uY));
00050     
00051     rot.axis[0]= uX.basicVector().v;
00052     rot.axis[1]= uY.basicVector().v;
00053     rot.axis[2]= uZ.basicVector().v;
00054     
00055   }
00056   
00061   TkRotation( const GlobalVector & uX, const GlobalVector & uY, 
00062               const GlobalVector & uZ) {
00063     rot.axis[0]= uX.basicVector().v;
00064     rot.axis[1]= uY.basicVector().v;
00065     rot.axis[2]= uZ.basicVector().v;
00066   }
00067   
00068   
00077   TkRotation( const Basic3DVector<T>& axis, T phi) :
00078     rot(  cos(phi), sin(phi), 0, 
00079           -sin(phi), cos(phi), 0,
00080           0,        0, 1) {
00081     
00082     //rotation around the z-axis by  phi
00083     TkRotation tmpRotz ( cos(axis.phi()), sin(axis.phi()), 0.,
00084                          -sin(axis.phi()), cos(axis.phi()), 0.,
00085                          0.,              0.,              1. );
00086     //rotation around y-axis by theta
00087     TkRotation tmpRoty ( cos(axis.theta()), 0.,-sin(axis.theta()),
00088                          0.,              1.,              0.,
00089                          sin(axis.theta()), 0., cos(axis.theta()) );
00090     (*this)*=tmpRoty;
00091     (*this)*=tmpRotz;      // =  this * tmpRoty * tmpRotz 
00092     
00093     // (tmpRoty * tmpRotz)^-1 * this * tmpRoty * tmpRotz
00094     
00095     *this = (tmpRoty*tmpRotz).multiplyInverse(*this);
00096     
00097   }
00098   /* this is the same thing...derived from the CLHEP ... it gives the
00099      same results MODULO the sign of the rotation....  but I don't want
00100      that... had 
00101      TkRotation (const Basic3DVector<T>& axis, float phi) {
00102      T cx = axis.x();
00103      T cy = axis.y();
00104      T cz = axis.z();
00105      
00106      T ll = axis.mag();
00107      if (ll == 0) {
00108      geometryDetails::TkRotationErr1();
00109      }else{
00110      
00111      float cosa = cos(phi), sina = sin(phi);
00112      cx /= ll; cy /= ll; cz /= ll;   
00113      
00114      R11 = cosa + (1-cosa)*cx*cx;
00115      R12 =        (1-cosa)*cx*cy - sina*cz;
00116      R13 =        (1-cosa)*cx*cz + sina*cy;
00117      
00118      R21 =        (1-cosa)*cy*cx + sina*cz;
00119      R22 = cosa + (1-cosa)*cy*cy; 
00120      R23 =        (1-cosa)*cy*cz - sina*cx;
00121      
00122      R31 =        (1-cosa)*cz*cx - sina*cy;
00123      R32 =        (1-cosa)*cz*cy + sina*cx;
00124      R33 = cosa + (1-cosa)*cz*cz;
00125      
00126      }
00127      
00128      }
00129   */
00130   
00131   template <typename U>
00132   TkRotation( const TkRotation<U>& a) : 
00133     rot (a.xx(), a.xy(), a.xz(), 
00134          a.yx(), a.yy(), a.yz(),
00135          a.zx(), a.zy(), a.zz()) {}
00136   
00137   TkRotation transposed() const {
00138     return rot.transpose();
00139   }
00140   
00141   Basic3DVector<T> operator*( const Basic3DVector<T>& v) const {
00142     return rot.rotate(v.v);
00143   }
00144   Basic3DVector<T> multiplyInverse( const Basic3DVector<T>& v) const {
00145     return rot.rotateBack(v.v);
00146   }
00147   
00148   template <class Scalar>
00149   Basic3DVector<Scalar> multiplyInverse( const Basic3DVector<Scalar>& v) const {
00150     return Basic3DVector<Scalar>( xx()*v.x() + yx()*v.y() + zx()*v.z(),
00151                                   xy()*v.x() + yy()*v.y() + zy()*v.z(),
00152                                   xz()*v.x() + yz()*v.y() + zz()*v.z());
00153   }
00154   
00155   Basic3DVector<T> operator*( const Basic2DVector<T>& v) const {
00156     return Basic3DVector<T>( xx()*v.x() + xy()*v.y(),
00157                              yx()*v.x() + yy()*v.y(),
00158                              zx()*v.x() + zy()*v.y());
00159   }
00160   Basic3DVector<T> multiplyInverse( const Basic2DVector<T>& v) const {
00161     return Basic3DVector<T>( xx()*v.x() + yx()*v.y(),
00162                              xy()*v.x() + yy()*v.y(),
00163                              xz()*v.x() + yz()*v.y());
00164   }
00165   
00166   
00167   
00168   TkRotation operator*( const TkRotation& b) const {
00169     return rot*b.rot;
00170   }
00171   TkRotation multiplyInverse( const TkRotation& b) const {
00172     return rot.transpose()*b.rot;
00173   }
00174   
00175   TkRotation& operator*=( const TkRotation& b) {
00176     return *this = operator * (b);
00177   }
00178   
00179   // Note a *= b; <=> a = a * b; while a.transform(b); <=> a = b * a;
00180   TkRotation& transform(const TkRotation& b) {
00181     return *this = b.operator * (*this);
00182   }
00183   
00184   TkRotation & rotateAxes(const Basic3DVector<T>& newX,
00185                           const Basic3DVector<T>& newY,
00186                           const Basic3DVector<T>& newZ) {
00187     T del = 0.001;
00188     
00189     if (
00190         
00191         // the check for right-handedness is not needed since
00192         // we want to change the handedness when it's left in cmsim
00193         //
00194         //       fabs(newZ.x()-w.x()) > del ||
00195         //       fabs(newZ.y()-w.y()) > del ||
00196         //       fabs(newZ.z()-w.z()) > del ||
00197         fabs(newX.mag2()-1.) > del ||
00198         fabs(newY.mag2()-1.) > del || 
00199         fabs(newZ.mag2()-1.) > del ||
00200         fabs(newX.dot(newY)) > del ||
00201         fabs(newY.dot(newZ)) > del ||
00202         fabs(newZ.dot(newX)) > del) {
00203       geometryDetails::TkRotationErr2();
00204       return *this;
00205     } else {
00206       return transform(TkRotation(newX.x(), newY.x(), newZ.x(),
00207                                   newX.y(), newY.y(), newZ.y(),
00208                                   newX.z(), newY.z(), newZ.z()));
00209     }
00210   }
00211   
00212   
00213   Basic3DVector<T> x() const { return rot.axis[0];}
00214   Basic3DVector<T> y() const { return rot.axis[1];}
00215   Basic3DVector<T> z() const { return rot.axis[2];}
00216   
00217   T xx() const { return rot.axis[0].arr[0];} 
00218   T xy() const { return rot.axis[0].arr[1];} 
00219   T xz() const { return rot.axis[0].arr[2];} 
00220   T yx() const { return rot.axis[1].arr[0];} 
00221   T yy() const { return rot.axis[1].arr[1];} 
00222   T yz() const { return rot.axis[1].arr[2];} 
00223   T zx() const { return rot.axis[2].arr[0];} 
00224   T zy() const { return rot.axis[2].arr[1];} 
00225   T zz() const { return rot.axis[2].arr[2];} 
00226   
00227 private:
00228   
00229   mathSSE::Rot3<T> rot;
00230   
00231 };
00232 
00233 
00234 template<>
00235 std::ostream & operator<< <float>( std::ostream& s, const TkRotation<float>& r);
00236 
00237 template<>
00238 std::ostream & operator<< <double>( std::ostream& s, const TkRotation<double>& r);
00239 
00240 
00241 template <class T, class U>
00242 inline Basic3DVector<U> operator*( const TkRotation<T>& r, const Basic3DVector<U>& v) {
00243   return Basic3DVector<U>( r.xx()*v.x() + r.xy()*v.y() + r.xz()*v.z(),
00244                            r.yx()*v.x() + r.yy()*v.y() + r.yz()*v.z(),
00245                            r.zx()*v.x() + r.zy()*v.y() + r.zz()*v.z());
00246 }
00247 
00248 template <class T, class U>
00249 inline TkRotation<typename PreciseFloatType<T,U>::Type>
00250 operator*( const TkRotation<T>& a, const TkRotation<U>& b) {
00251     typedef TkRotation<typename PreciseFloatType<T,U>::Type> RT;
00252     return RT( a.xx()*b.xx() + a.xy()*b.yx() + a.xz()*b.zx(),
00253                a.xx()*b.xy() + a.xy()*b.yy() + a.xz()*b.zy(),
00254                a.xx()*b.xz() + a.xy()*b.yz() + a.xz()*b.zz(),
00255                a.yx()*b.xx() + a.yy()*b.yx() + a.yz()*b.zx(),
00256                a.yx()*b.xy() + a.yy()*b.yy() + a.yz()*b.zy(),
00257                a.yx()*b.xz() + a.yy()*b.yz() + a.yz()*b.zz(),
00258                a.zx()*b.xx() + a.zy()*b.yx() + a.zz()*b.zx(),
00259                a.zx()*b.xy() + a.zy()*b.yy() + a.zz()*b.zy(),
00260                a.zx()*b.xz() + a.zy()*b.yz() + a.zz()*b.zz());
00261 }
00262 
00263 #endif
00264 
00265 
00266 
00267