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
00083 TkRotation tmpRotz ( cos(axis.phi()), sin(axis.phi()), 0.,
00084 -sin(axis.phi()), cos(axis.phi()), 0.,
00085 0., 0., 1. );
00086
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;
00092
00093
00094
00095 *this = (tmpRoty*tmpRotz).multiplyInverse(*this);
00096
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 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
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
00192
00193
00194
00195
00196
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