CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/DataFormats/GeometrySurface/interface/oldTkRotation.h

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