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
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 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
00084 TkRotation tmpRotz ( cos(axis.phi()), sin(axis.phi()), 0.,
00085 -sin(axis.phi()), cos(axis.phi()), 0.,
00086 0., 0., 1. );
00087
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;
00093
00094
00095
00096 *this = (tmpRoty*tmpRotz).multiplyInverse(*this);
00097
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
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
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
00219
00220
00221
00222
00223
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