00001 #ifndef GeometryVector_newBasic3DVector_h
00002 #define GeometryVector_newBasic3DVector_h
00003
00004 #include "DataFormats/GeometryVector/interface/Basic2DVector.h"
00005 #include "DataFormats/GeometryVector/interface/Theta.h"
00006 #include "DataFormats/GeometryVector/interface/Phi.h"
00007 #include "DataFormats/GeometryVector/interface/PreciseFloatType.h"
00008 #include "DataFormats/GeometryVector/interface/CoordinateSets.h"
00009 #include "DataFormats/Math/interface/SSEVec.h"
00010 #include <iosfwd>
00011 #include <cmath>
00012
00013 template < typename T>
00014 class Basic3DVector {
00015 public:
00016
00017 typedef T ScalarType;
00018 typedef Geom::Cylindrical2Cartesian<T> Cylindrical;
00019 typedef Geom::Spherical2Cartesian<T> Spherical;
00020 typedef Spherical Polar;
00021
00026 Basic3DVector() {}
00027
00029 Basic3DVector( const Basic3DVector & p) :
00030 v(p.x(),p.y(),p.z()) {}
00031
00033 template <class U>
00034 Basic3DVector( const Basic3DVector<U> & p) :
00035 v(p.x(),p.y(),p.z()) {}
00036
00037
00039 Basic3DVector( const Basic2DVector<T> & p) :
00040 v(p.x(),p.y(),0) {}
00041
00042
00051 template <class OtherPoint>
00052 explicit Basic3DVector( const OtherPoint& p) :
00053 v(p.x(),p.y(),p.z()) {}
00054
00055
00056
00057 Basic3DVector(mathSSE::Vec4<T> const& iv) : v(iv){}
00058
00060 Basic3DVector( const T& x, const T& y, const T& z) :
00061 v(x,y,z){}
00062
00067 template <typename U>
00068 Basic3DVector( const Geom::Theta<U>& theta,
00069 const Geom::Phi<U>& phi, const T& r) {
00070 Polar p( theta.value(), phi.value(), r);
00071 v.o.theX = p.x(); v.o.theY = p.y(); v.o.theZ = p.z();
00072 }
00073
00075 T x() const { return v.o.theX;}
00076
00078 T y() const { return v.o.theY;}
00079
00081 T z() const { return v.o.theZ;}
00082
00083 Basic2DVector<T> xy() const { return v.xy();}
00084
00085
00086 bool operator==(const Basic3DVector& rh) const {
00087 return x()==rh.x() && y()==rh.y() && z()==rh.z();
00088 }
00089
00091 T mag2() const { return x()*x() + y()*y()+z()*z();}
00092
00094 T mag() const { return std::sqrt( mag2());}
00095
00097 T perp2() const { return x()*x() + y()*y();}
00098
00100 T perp() const { return std::sqrt( perp2());}
00101
00103 T transverse() const { return perp();}
00104
00109 T barePhi() const {return std::atan2(y(),x());}
00110 Geom::Phi<T> phi() const {return Geom::Phi<T>(barePhi());}
00111
00116 T bareTheta() const {return std::atan2(perp(),z());}
00117 Geom::Theta<T> theta() const {return Geom::Theta<T>(std::atan2(perp(),z()));}
00118
00123
00124 T eta() const { T x(z()/perp()); return std::log(x+std::sqrt(x*x+T(1)));}
00125
00129 Basic3DVector unit() const {
00130 T my_mag = mag2();
00131 if (my_mag==0) return *this;
00132 my_mag = T(1)/std::sqrt(my_mag);
00133 return *this * my_mag;
00134 }
00135
00138 template <class U>
00139 Basic3DVector& operator+= ( const Basic3DVector<U>& p) {
00140 v.o.theX += p.x();
00141 v.o.theY += p.y();
00142 v.o.theZ += p.z();
00143 return *this;
00144 }
00145
00148 template <class U>
00149 Basic3DVector& operator-= ( const Basic3DVector<U>& p) {
00150 v.o.theX -= p.x();
00151 v.o.theY -= p.y();
00152 v.o.theZ -= p.z();
00153 return *this;
00154 }
00155
00157 Basic3DVector operator-() const { return Basic3DVector(-x(),-y(),-z());}
00158
00160 Basic3DVector& operator*= ( T t) {
00161 v.o.theX *= t;
00162 v.o.theY *= t;
00163 v.o.theZ *= t;
00164 return *this;
00165 }
00166
00168 Basic3DVector& operator/= ( T t) {
00169 t = T(1)/t;
00170 v.o.theX *= t;
00171 v.o.theY *= t;
00172 v.o.theZ *= t;
00173 return *this;
00174 }
00175
00177 T dot( const Basic3DVector& v) const {
00178 return x()*v.x() + y()*v.y() + z()*v.z();
00179 }
00180
00186 template <class U>
00187 typename PreciseFloatType<T,U>::Type dot( const Basic3DVector<U>& v) const {
00188 return x()*v.x() + y()*v.y() + z()*v.z();
00189 }
00190
00192 Basic3DVector cross( const Basic3DVector& v) const {
00193 return Basic3DVector( y()*v.z() - v.y()*z(),
00194 z()*v.x() - v.z()*x(),
00195 x()*v.y() - v.x()*y());
00196 }
00197
00203 template <class U>
00204 Basic3DVector<typename PreciseFloatType<T,U>::Type>
00205 cross( const Basic3DVector<U>& v) const {
00206 return Basic3DVector<typename PreciseFloatType<T,U>::Type>( y()*v.z() - v.y()*z(),
00207 z()*v.x() - v.z()*x(),
00208 x()*v.y() - v.x()*y());
00209 }
00210
00211 public:
00212 mathSSE::Vec4<T> v;
00213 } __attribute__ ((aligned (16)));
00214
00215
00216 namespace geometryDetails {
00217 std::ostream & print3D(std::ostream& s, double x, double y, double z);
00218 }
00219
00221 template <class T>
00222 inline std::ostream & operator<<( std::ostream& s, const Basic3DVector<T>& v) {
00223 return geometryDetails::print3D(s, v.x(),v.y(), v.z());
00224 }
00225
00226
00228 template <class T, class U>
00229 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00230 operator+( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00231 typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00232 return RT(a.x()+b.x(), a.y()+b.y(), a.z()+b.z());
00233 }
00234
00235 template <class T, class U>
00236 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00237 operator-( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00238 typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00239 return RT(a.x()-b.x(), a.y()-b.y(), a.z()-b.z());
00240 }
00241
00243 template <class T>
00244 inline T operator*( const Basic3DVector<T>& v1, const Basic3DVector<T>& v2) {
00245 return v1.dot(v2);
00246 }
00247
00249 template <class T, class U>
00250 inline typename PreciseFloatType<T,U>::Type operator*( const Basic3DVector<T>& v1,
00251 const Basic3DVector<U>& v2) {
00252 return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z();
00253 }
00254
00258 template <class T>
00259 inline Basic3DVector<T> operator*( const Basic3DVector<T>& v, T t) {
00260 return Basic3DVector<T>(v.x()*t, v.y()*t, v.z()*t);
00261 }
00262
00264 template <class T>
00265 inline Basic3DVector<T> operator*(T t, const Basic3DVector<T>& v) {
00266 return Basic3DVector<T>(v.x()*t, v.y()*t, v.z()*t);
00267 }
00268
00269 template <class T, typename S>
00270 inline Basic3DVector<T> operator*(S t, const Basic3DVector<T>& v) {
00271 return static_cast<T>(t)*v;
00272 }
00273
00274 template <class T, typename S>
00275 inline Basic3DVector<T> operator*(const Basic3DVector<T>& v, S t) {
00276 return static_cast<T>(t)*v;
00277 }
00278
00279
00283 template <class T, typename S>
00284 inline Basic3DVector<T> operator/( const Basic3DVector<T>& v, S s) {
00285 T t = T(1)/s;
00286 return v*t;
00287 }
00288
00289
00290 typedef Basic3DVector<float> Basic3DVectorF;
00291 typedef Basic3DVector<double> Basic3DVectorD;
00292
00293 #include "DataFormats/GeometryVector/interface/Basic3DVectorFSSE.icc"
00294
00295
00296 #endif // GeometryVector_Basic3DVector_h
00297
00298