CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DataFormats/GeometryVector/interface/sseBasic2DVector.h

Go to the documentation of this file.
00001 #ifndef GeometryVector_newBasic2DVector_h
00002 #define GeometryVector_newBasic2DVector_h
00003 
00004 #include "DataFormats/GeometryVector/interface/Phi.h"
00005 #include "DataFormats/GeometryVector/interface/PreciseFloatType.h"
00006 #include "DataFormats/GeometryVector/interface/CoordinateSets.h"
00007 #include "DataFormats/Math/interface/SSEVec.h"
00008 
00009 
00010 #include <cmath>
00011 #include <iosfwd>
00012 
00013 
00014 template < class T> 
00015 class Basic2DVector {
00016 public:
00017 
00018   typedef T    ScalarType;
00019   typedef mathSSE::Vec2<T> VectorType;
00020   typedef mathSSE::Vec2<T> MathVector;
00021   typedef Geom::Polar2Cartesian<T>        Polar;
00022 
00027   Basic2DVector() {}
00028 
00030   Basic2DVector( const Basic2DVector & p) : v(p.v) {}
00031 
00032   template<typename U>
00033   Basic2DVector( const Basic2DVector<U> & p) : v(p.v) {}
00034 
00035 
00043   template <class Other> 
00044   explicit Basic2DVector( const Other& p) : v(p.x(),p.y()) {}
00045 
00047   Basic2DVector( const T& x, const T& y) : v(x,y) {}
00048 
00049   // constructor from Vec2 or vec4
00050   template<typename U>
00051   Basic2DVector(mathSSE::Vec2<U> const& iv) : v(iv){}
00052   template<typename U>
00053   Basic2DVector(mathSSE::Vec4<U> const& iv) : v(iv.xy()){}
00054 
00055   MathVector const & mathVector() const { return v;}
00056   MathVector & mathVector() { return v;}
00057 
00058   T operator[](int i) const { return v[i];}
00059   T & operator[](int i) { return v[i];}
00060 
00062   T x() const { return v[0];}
00063 
00065   T y() const { return v[1];}
00066 
00068   T mag2() const { return ::dot(v,v);}
00069 
00071   T mag() const  { return std::sqrt( mag2());}
00072 
00074   T r() const    { return mag();}
00075 
00080   T barePhi() const {return std::atan2(y(),x());}
00081   Geom::Phi<T> phi() const {return Geom::Phi<T>(atan2(y(),x()));}
00082 
00086   Basic2DVector unit() const {
00087     T my_mag = mag();
00088     return my_mag == 0 ? *this : *this / my_mag;
00089   }
00090 
00093   template <class U> 
00094   Basic2DVector& operator+= ( const Basic2DVector<U>& p) {
00095     v = v + p.v;
00096     return *this;
00097   } 
00098 
00101   template <class U> 
00102   Basic2DVector& operator-= ( const Basic2DVector<U>& p) {
00103     v = v - p.v;
00104     return *this;
00105   } 
00106 
00108   Basic2DVector operator-() const { return Basic2DVector(-v);}
00109 
00111   Basic2DVector& operator*= ( T t) {
00112     v = v*t;
00113     return *this;
00114   } 
00115 
00117   Basic2DVector& operator/= ( T t) {
00118     t = T(1)/t;
00119     v = v*t;
00120     return *this;
00121   } 
00122 
00124   T dot( const Basic2DVector& lh) const { return ::dot(v,lh.v);}
00125 
00131   template <class U> 
00132   typename PreciseFloatType<T,U>::Type dot( const Basic2DVector<U>& lh) const { 
00133     return Basic2DVector<typename PreciseFloatType<T,U>::Type>(*this)
00134       .dot(Basic2DVector<typename PreciseFloatType<T,U>::Type>(lh));
00135   }
00136 
00138   T cross( const Basic2DVector& lh) const { return ::cross(v,lh.v);}
00139 
00145   template <class U> 
00146   typename PreciseFloatType<T,U>::Type cross( const Basic2DVector<U>& lh) const { 
00147     return Basic2DVector<typename PreciseFloatType<T,U>::Type>(*this)
00148       .cross(Basic2DVector<typename PreciseFloatType<T,U>::Type>(lh));
00149   }
00150 
00151 
00152 public:
00153 
00154   mathSSE::Vec2<T> v;
00155 
00156 };
00157 
00158 
00159 namespace geometryDetails {
00160   std::ostream & print2D(std::ostream& s, double x, double y);
00161 
00162 }
00163 
00165 template <class T>
00166 inline std::ostream & operator<<( std::ostream& s, const Basic2DVector<T>& v) {
00167   return geometryDetails::print2D(s, v.x(),v.y());
00168 }
00169 
00170 
00172 template <class T>
00173 inline Basic2DVector<T>
00174 operator+( const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
00175   return a.v+b.v;
00176 }
00177 template <class T>
00178 inline Basic2DVector<T>
00179 operator-( const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
00180   return a.v-b.v;
00181 }
00182 
00183 template <class T, class U>
00184 inline Basic2DVector<typename PreciseFloatType<T,U>::Type>
00185 operator+( const Basic2DVector<T>& a, const Basic2DVector<U>& b) {
00186   typedef Basic2DVector<typename PreciseFloatType<T,U>::Type> RT;
00187   return RT(a) + RT(b);
00188 }
00189 
00190 template <class T, class U>
00191 inline Basic2DVector<typename PreciseFloatType<T,U>::Type>
00192 operator-( const Basic2DVector<T>& a, const Basic2DVector<U>& b) {
00193   typedef Basic2DVector<typename PreciseFloatType<T,U>::Type> RT;
00194   return RT(a)-RT(b);
00195 }
00196 
00197 
00198 
00199 
00200 // scalar product of vectors of same precision
00201 template <class T>
00202 inline T operator*( const Basic2DVector<T>& v1, const Basic2DVector<T>& v2) {
00203   return v1.dot(v2);
00204 }
00205 
00207 template <class T, class U>
00208 inline typename PreciseFloatType<T,U>::Type operator*( const Basic2DVector<T>& v1, 
00209                                                        const Basic2DVector<U>& v2) {
00210   return v1.dot(v2);
00211 }
00212 
00213 
00217 template <class T>
00218 inline Basic2DVector<T> operator*( const Basic2DVector<T>& v, T t) {
00219   return v.v*t;
00220 }
00221 
00223 template <class T>
00224 inline Basic2DVector<T> operator*(T t, const Basic2DVector<T>& v) {
00225   return v.v*t;
00226 }
00227 
00228 
00229 
00230 template <class T, class Scalar>
00231 inline Basic2DVector<T> operator*( const Basic2DVector<T>& v, const Scalar& s) {
00232   T t = static_cast<T>(s);
00233   return v*t;
00234 }
00235 
00237 template <class T, class Scalar>
00238 inline Basic2DVector<T> operator*( const Scalar& s, const Basic2DVector<T>& v) {
00239   T t = static_cast<T>(s);
00240   return v*t;
00241 }
00242 
00246 template <class T>
00247 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, T t) {
00248   return v.v/t;
00249 }
00250 
00251 template <class T, class Scalar>
00252 inline Basic2DVector<T> operator/( const Basic2DVector<T>& v, const Scalar& s) {
00253   //   T t = static_cast<T>(Scalar(1)/s); return v*t;
00254    T t = static_cast<T>(s);
00255   return v/t;
00256 }
00257 
00258 typedef Basic2DVector<float> Basic2DVectorF;
00259 typedef Basic2DVector<double> Basic2DVectorD;
00260 
00261 
00262 #endif // GeometryVector_Basic2DVector_h