00001 #ifndef GeometryVector_Basic3DVector_h
00002 #define GeometryVector_Basic3DVector_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 <iosfwd>
00010 #include <iostream>
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() : theX( T()), theY( T()), theZ( T()) {}
00027
00029 Basic3DVector( const Basic3DVector & p) :
00030 theX(p.x()), theY(p.y()), theZ(p.z()) {}
00031
00033 template <class U>
00034 Basic3DVector( const Basic3DVector<U> & p) :
00035 theX(p.x()), theY(p.y()), theZ(p.z()) {}
00036
00038 Basic3DVector( const Basic2DVector<T> & p) :
00039 theX(p.x()), theY(p.y()), theZ(0) {}
00040
00049 template <class OtherPoint>
00050 explicit Basic3DVector( const OtherPoint& p) :
00051 theX(p.x()), theY(p.y()), theZ(p.z()) {}
00052
00054 Basic3DVector( const T& x, const T& y, const T& z) :
00055 theX(x), theY(y), theZ(z) {}
00056
00061 template <typename U>
00062 Basic3DVector( const Geom::Theta<U>& theta,
00063 const Geom::Phi<U>& phi, const T& r) {
00064 Polar p( theta.value(), phi.value(), r);
00065 theX = p.x(); theY = p.y(); theZ = p.z();
00066 }
00067
00069 T x() const { return theX;}
00070
00072 T y() const { return theY;}
00073
00075 T z() const { return theZ;}
00076
00078 T mag2() const { return theX*theX + theY*theY + theZ*theZ;}
00079
00081 T mag() const { return sqrt( mag2());}
00082
00084 T perp2() const { return x()*x() + y()*y();}
00085
00087 T perp() const { return sqrt( perp2());}
00088
00090 T transverse() const { return perp();}
00091
00096 T barePhi() const {return atan2(theY,theX);}
00097 Geom::Phi<T> phi() const {return Geom::Phi<T>(atan2(theY,theX));}
00098
00103 T bareTheta() const {return atan2(perp(),z());}
00104 Geom::Theta<T> theta() const {return Geom::Theta<T>(atan2(perp(),z()));}
00105
00110
00111 T eta() const { T x(z()/perp()); return log(x+sqrt(x*x+1));}
00112
00116 Basic3DVector unit() const {
00117 T my_mag = mag();
00118 return my_mag == 0 ? *this : *this / my_mag;
00119 }
00120
00123 template <class U>
00124 Basic3DVector& operator+= ( const Basic3DVector<U>& p) {
00125 theX += p.x();
00126 theY += p.y();
00127 theZ += p.z();
00128 return *this;
00129 }
00130
00133 template <class U>
00134 Basic3DVector& operator-= ( const Basic3DVector<U>& p) {
00135 theX -= p.x();
00136 theY -= p.y();
00137 theZ -= p.z();
00138 return *this;
00139 }
00140
00142 Basic3DVector operator-() const { return Basic3DVector(-x(),-y(),-z());}
00143
00145 Basic3DVector& operator*= ( const T& t) {
00146 theX *= t;
00147 theY *= t;
00148 theZ *= t;
00149 return *this;
00150 }
00151
00153 Basic3DVector& operator/= ( const T& t) {
00154 theX /= t;
00155 theY /= t;
00156 theZ /= t;
00157 return *this;
00158 }
00159
00161 T dot( const Basic3DVector& v) const {
00162 return x()*v.x() + y()*v.y() + z()*v.z();
00163 }
00164
00170 template <class U>
00171 typename PreciseFloatType<T,U>::Type dot( const Basic3DVector<U>& v) const {
00172 return x()*v.x() + y()*v.y() + z()*v.z();
00173 }
00174
00176 Basic3DVector cross( const Basic3DVector& v) const {
00177 return Basic3DVector( y()*v.z() - v.y()*z(),
00178 z()*v.x() - v.z()*x(),
00179 x()*v.y() - v.x()*y());
00180 }
00181
00187 template <class U>
00188 Basic3DVector<typename PreciseFloatType<T,U>::Type>
00189 cross( const Basic3DVector<U>& v) const {
00190 return Basic3DVector<typename PreciseFloatType<T,U>::Type>( y()*v.z() - v.y()*z(),
00191 z()*v.x() - v.z()*x(),
00192 x()*v.y() - v.x()*y());
00193 }
00194
00195 private:
00196 T theX;
00197 T theY;
00198 T theZ;
00199 };
00200
00202 template <class T>
00203 inline std::ostream & operator<<( std::ostream& s, const Basic3DVector<T>& v) {
00204 return s << " (" << v.x() << ',' << v.y() << ',' << v.z() << ") ";
00205 }
00206
00208 template <class T, class U>
00209 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00210 operator+( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00211 typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00212 return RT(a.x()+b.x(), a.y()+b.y(), a.z()+b.z());
00213 }
00214
00215 template <class T, class U>
00216 inline Basic3DVector<typename PreciseFloatType<T,U>::Type>
00217 operator-( const Basic3DVector<T>& a, const Basic3DVector<U>& b) {
00218 typedef Basic3DVector<typename PreciseFloatType<T,U>::Type> RT;
00219 return RT(a.x()-b.x(), a.y()-b.y(), a.z()-b.z());
00220 }
00221
00223 template <class T>
00224 inline T operator*( const Basic3DVector<T>& v1, const Basic3DVector<T>& v2) {
00225 return v1.dot(v2);
00226 }
00227
00229 template <class T, class U>
00230 inline typename PreciseFloatType<T,U>::Type operator*( const Basic3DVector<T>& v1,
00231 const Basic3DVector<U>& v2) {
00232 return v1.x()*v2.x() + v1.y()*v2.y() + v1.z()*v2.z();
00233 }
00234
00238 template <class T, class Scalar>
00239 inline Basic3DVector<T> operator*( const Basic3DVector<T>& v, const Scalar& s) {
00240 T t = static_cast<T>(s);
00241 return Basic3DVector<T>(v.x()*t, v.y()*t, v.z()*t);
00242 }
00243
00245 template <class T, class Scalar>
00246 inline Basic3DVector<T> operator*( const Scalar& s, const Basic3DVector<T>& v) {
00247 T t = static_cast<T>(s);
00248 return Basic3DVector<T>(v.x()*t, v.y()*t, v.z()*t);
00249 }
00250
00254 template <class T, class Scalar>
00255 inline Basic3DVector<T> operator/( const Basic3DVector<T>& v, const Scalar& s) {
00256 T t = static_cast<T>(s);
00257 return Basic3DVector<T>(v.x()/t, v.y()/t, v.z()/t);
00258 }
00259
00260 #endif // GeometryVector_Basic3DVector_h
00261
00262