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/ExtVec.h"
00010 #include <iosfwd>
00011 #include <cmath>
00012
00013 namespace detailsBasic3DVector {
00014 inline float __attribute__((always_inline)) __attribute__ ((pure))
00015 eta(float x, float y, float z) { float t(z/std::sqrt(x*x+y*y)); return ::asinhf(t);}
00016 inline double __attribute__((always_inline)) __attribute__ ((pure))
00017 eta(double x, double y, double z) { double t(z/std::sqrt(x*x+y*y)); return ::asinh(t);}
00018 inline long double __attribute__((always_inline)) __attribute__ ((pure))
00019 eta(long double x, long double y, long double z) { long double t(z/std::sqrt(x*x+y*y)); return ::asinhl(t);}
00020 }
00021
00022
00023 template < typename T>
00024 class Basic3DVector {
00025 public:
00026
00027 typedef T ScalarType;
00028 typedef Vec4<T> VectorType;
00029 typedef Vec4<T> MathVector;
00030 typedef Geom::Cylindrical2Cartesian<T> Cylindrical;
00031 typedef Geom::Spherical2Cartesian<T> Spherical;
00032 typedef Spherical Polar;
00033
00038 Basic3DVector() : v{0,0,0,0} {}
00039
00041 Basic3DVector( const Basic3DVector & p) :
00042 v(p.v) {}
00043
00045 template <class U>
00046 Basic3DVector( const Basic3DVector<U> & p) :
00047 v{T(p.v[0]),T(p.v[1]),T(p.v[2]),T(p.v[3])} {}
00048
00049
00051 Basic3DVector( const Basic2DVector<T> & p) :
00052 v{p.x(),p.y(),0} {}
00053
00054
00063 template <class OtherPoint>
00064 explicit Basic3DVector( const OtherPoint& p) :
00065 v{T(p.x()),T(p.y()),T(p.z())} {}
00066
00067
00068
00069 Basic3DVector(MathVector const& iv) :
00070 v(iv) {}
00071
00072 template<class U>
00073 Basic3DVector(Vec4<U> const& iv) :
00074 v{T(iv[0]),T(iv[1]),T(iv[2]),T(iv[3])} {}
00075
00077 Basic3DVector( const T& x, const T& y, const T& z, const T&w=0) :
00078 v{x,y,z,w}{}
00079
00084 template <typename U>
00085 Basic3DVector( const Geom::Theta<U>& theta,
00086 const Geom::Phi<U>& phi, const T& r) {
00087 Polar p( theta.value(), phi.value(), r);
00088 v[0] = p.x(); v[1] = p.y(); v[2] = p.z();
00089 }
00090
00091 MathVector const & mathVector() const { return v;}
00092 MathVector & mathVector() { return v;}
00093
00094 T operator[](int i) const { return v[i];}
00095 T & operator[](int i) { return v[i];}
00096
00097
00099 T x() const { return v[0];}
00100
00102 T y() const { return v[1];}
00103
00105 T z() const { return v[2];}
00106
00107 T w() const { return v[3];}
00108
00109 Basic2DVector<T> xy() const { return ::xy(v);}
00110
00111
00112 bool operator==(const Basic3DVector& rh) const {
00113 auto res = v==rh.v;
00114 return res[0]&res[1]&res[2]&res[3];
00115 }
00116
00118 T mag2() const { return ::dot(v,v);}
00119
00121 T mag() const { return std::sqrt( mag2());}
00122
00124 T perp2() const { return ::dot2(v,v);}
00125
00127 T perp() const { return std::sqrt( perp2());}
00128
00130 T transverse() const { return perp();}
00131
00136 T barePhi() const {return std::atan2(y(),x());}
00137 Geom::Phi<T> phi() const {return Geom::Phi<T>(barePhi());}
00138
00143 T bareTheta() const {return std::atan2(perp(),z());}
00144 Geom::Theta<T> theta() const {return Geom::Theta<T>(std::atan2(perp(),z()));}
00145
00150
00151 T eta() const { return detailsBasic3DVector::eta(x(),y(),z());}
00152
00156 Basic3DVector unit() const {
00157 T my_mag = mag2();
00158 return (0!=my_mag) ? (*this)*(T(1)/std::sqrt(my_mag)) : *this;
00159 }
00160
00163 template <class U>
00164 Basic3DVector& operator+= ( const Basic3DVector<U>& p) {
00165 v = v + p.v;
00166 return *this;
00167 }
00168
00171 template <class U>
00172 Basic3DVector& operator-= ( const Basic3DVector<U>& p) {
00173 v = v - p.v;
00174 return *this;
00175 }
00176
00178 Basic3DVector operator-() const { return Basic3DVector(-v);}
00179
00181 Basic3DVector& operator*= ( T t) {
00182 v = t*v;
00183 return *this;
00184 }
00185
00187 Basic3DVector& operator/= ( T t) {
00188
00189 v = v/t;
00190 return *this;
00191 }
00192
00194 T dot( const Basic3DVector& rh) const {
00195 return ::dot(v,rh.v);
00196 }
00197
00203 template <class U>
00204 typename PreciseFloatType<T,U>::Type dot( const Basic3DVector<U>& lh) const {
00205 return Basic3DVector<typename PreciseFloatType<T,U>::Type>(*this)
00206 .dot(Basic3DVector<typename PreciseFloatType<T,U>::Type>(lh));
00207 }
00208
00210 Basic3DVector cross( const Basic3DVector& lh) const {
00211 return ::cross3(v,lh.v);
00212 }
00213
00214
00220 template <class U>
00221 Basic3DVector<typename PreciseFloatType<T,U>::Type>
00222 cross( const Basic3DVector<U>& lh) const {
00223 return Basic3DVector<typename PreciseFloatType<T,U>::Type>(*this)
00224 .cross(Basic3DVector<typename PreciseFloatType<T,U>::Type>(lh));
00225 }
00226
00227 public:
00228 Vec4<T> v;
00229 } __attribute__ ((aligned (16)));
00230
00231
00232 namespace geometryDetails {
00233 std::ostream & print3D(std::ostream& s, double x, double y, double z);
00234 }
00235
00237 template <class T>
00238 inline std::ostream & operator<<( std::ostream& s, const Basic3DVector<T>& v) {
00239 return geometryDetails::print3D(s, v.x(),v.y(), v.z());
00240 }
00241
00242
00244 template <class T>
00245 inline Basic3DVector<T>
00246 operator+( const Basic3DVector<T>& a, const Basic3DVector<T>& b) {
00247 return a.v+b.v;
00248 }
00249 template <class T>
00250 inline Basic3DVector<T>
00251 operator-( const Basic3DVector<T>& a, const Basic3DVector<T>& b) {
00252 return a.v-b.v;
00253 }
00254
00255 template <class T, class U>
00256 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00257 operator+( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00258 typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00259 return RT(a).v+RT(b).v;
00260 }
00261
00262 template <class T, class U>
00263 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00264 operator-( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00265 typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00266 return RT(a).v-RT(b).v;
00267 }
00268
00270 template <class T>
00271 inline T operator*( const Basic3DVector<T>& v1, const Basic3DVector<T>& v2) {
00272 return v1.dot(v2);
00273 }
00274
00276 template <class T, class U>
00277 inline typename PreciseFloatType<T,U>::Type operator*( const Basic3DVector<T>& v1,
00278 const Basic3DVector<U>& v2) {
00279 return v1.dot(v2);
00280 }
00281
00285 template <class T>
00286 inline Basic3DVector<T> operator*( const Basic3DVector<T>& v, T t) {
00287 return v.v*t;
00288 }
00289
00291 template <class T>
00292 inline Basic3DVector<T> operator*(T t, const Basic3DVector<T>& v) {
00293 return v.v*t;
00294 }
00295
00296
00297
00298 template <class T, typename S>
00299 inline Basic3DVector<T> operator*(S t, const Basic3DVector<T>& v) {
00300 return static_cast<T>(t)*v;
00301 }
00302
00303 template <class T, typename S>
00304 inline Basic3DVector<T> operator*(const Basic3DVector<T>& v, S t) {
00305 return static_cast<T>(t)*v;
00306 }
00307
00308
00312 template <class T>
00313 inline Basic3DVector<T> operator/(const Basic3DVector<T>& v, T t) {
00314 return v.v/t;
00315 }
00316
00317 template <class T, typename S>
00318 inline Basic3DVector<T> operator/( const Basic3DVector<T>& v, S s) {
00319
00320 T t = s;
00321 return v/t;
00322 }
00323
00324
00325 typedef Basic3DVector<float> Basic3DVectorF;
00326 typedef Basic3DVector<double> Basic3DVectorD;
00327
00328
00329
00330 #include "Basic3DVectorLD.h"
00331
00332 #endif // GeometryVector_Basic3DVector_h
00333
00334