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
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
00060 T x() const { return v[0];}
00061
00063 T y() const { return v[1];}
00064
00066 T mag2() const { return ::dot(v,v);}
00067
00069 T mag() const { return std::sqrt( mag2());}
00070
00072 T r() const { return mag();}
00073
00078 T barePhi() const {return std::atan2(y(),x());}
00079 Geom::Phi<T> phi() const {return Geom::Phi<T>(atan2(y(),x()));}
00080
00084 Basic2DVector unit() const {
00085 T my_mag = mag();
00086 return my_mag == 0 ? *this : *this / my_mag;
00087 }
00088
00091 template <class U>
00092 Basic2DVector& operator+= ( const Basic2DVector<U>& p) {
00093 v = v + p.v;
00094 return *this;
00095 }
00096
00099 template <class U>
00100 Basic2DVector& operator-= ( const Basic2DVector<U>& p) {
00101 v = v - p.v;
00102 return *this;
00103 }
00104
00106 Basic2DVector operator-() const { return Basic2DVector(-v);}
00107
00109 Basic2DVector& operator*= ( T t) {
00110 v = v*t;
00111 return *this;
00112 }
00113
00115 Basic2DVector& operator/= ( T t) {
00116 t = T(1)/t;
00117 v = v*t;
00118 return *this;
00119 }
00120
00122 T dot( const Basic2DVector& lh) const { return ::dot(v,lh.v);}
00123
00129 template <class U>
00130 typename PreciseFloatType<T,U>::Type dot( const Basic2DVector<U>& lh) const {
00131 return Basic2DVector<typename PreciseFloatType<T,U>::Type>(*this)
00132 .dot(Basic2DVector<typename PreciseFloatType<T,U>::Type>(lh));
00133 }
00134
00136 T cross( const Basic2DVector& lh) const { return ::cross(v,lh.v);}
00137
00143 template <class U>
00144 typename PreciseFloatType<T,U>::Type cross( const Basic2DVector<U>& lh) const {
00145 return Basic2DVector<typename PreciseFloatType<T,U>::Type>(*this)
00146 .cross(Basic2DVector<typename PreciseFloatType<T,U>::Type>(lh));
00147 }
00148
00149
00150 public:
00151
00152 mathSSE::Vec2<T> v;
00153
00154 };
00155
00156
00157 namespace geometryDetails {
00158 std::ostream & print2D(std::ostream& s, double x, double y);
00159
00160 }
00161
00163 template <class T>
00164 inline std::ostream & operator<<( std::ostream& s, const Basic2DVector<T>& v) {
00165 return geometryDetails::print2D(s, v.x(),v.y());
00166 }
00167
00168
00170 template <class T>
00171 inline Basic2DVector<T>
00172 operator+( const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
00173 return a.v+b.v;
00174 }
00175 template <class T>
00176 inline Basic2DVector<T>
00177 operator-( const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
00178 return a.v-b.v;
00179 }
00180
00181 template <class T, class U>
00182 inline Basic2DVector<typename PreciseFloatType<T,U>::Type>
00183 operator+( const Basic2DVector<T>& a, const Basic2DVector<U>& b) {
00184 typedef Basic2DVector<typename PreciseFloatType<T,U>::Type> RT;
00185 return RT(a) + RT(b);
00186 }
00187
00188 template <class T, class U>
00189 inline Basic2DVector<typename PreciseFloatType<T,U>::Type>
00190 operator-( const Basic2DVector<T>& a, const Basic2DVector<U>& b) {
00191 typedef Basic2DVector<typename PreciseFloatType<T,U>::Type> RT;
00192 return RT(a)-RT(b);
00193 }
00194
00195
00196
00197
00198
00199 template <class T>
00200 inline T operator*( const Basic2DVector<T>& v1, const Basic2DVector<T>& v2) {
00201 return v1.dot(v2);
00202 }
00203
00205 template <class T, class U>
00206 inline typename PreciseFloatType<T,U>::Type operator*( const Basic2DVector<T>& v1,
00207 const Basic2DVector<U>& v2) {
00208 return v1.dot(v2);
00209 }
00210
00211
00215 template <class T>
00216 inline Basic2DVector<T> operator*( const Basic2DVector<T>& v, T t) {
00217 return v.v*t;
00218 }
00219
00221 template <class T>
00222 inline Basic2DVector<T> operator*(T t, const Basic2DVector<T>& v) {
00223 return v.v*t;
00224 }
00225
00226
00227
00228 template <class T, class Scalar>
00229 inline Basic2DVector<T> operator*( const Basic2DVector<T>& v, const Scalar& s) {
00230 T t = static_cast<T>(s);
00231 return v*t;
00232 }
00233
00235 template <class T, class Scalar>
00236 inline Basic2DVector<T> operator*( const Scalar& s, const Basic2DVector<T>& v) {
00237 T t = static_cast<T>(s);
00238 return v*t;
00239 }
00240
00244 template <class T>
00245 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, T t) {
00246 return v.v/t;
00247 }
00248
00249 template <class T, class Scalar>
00250 inline Basic2DVector<T> operator/( const Basic2DVector<T>& v, const Scalar& s) {
00251
00252 T t = static_cast<T>(s);
00253 return v/t;
00254 }
00255
00256 typedef Basic2DVector<float> Basic2DVectorF;
00257 typedef Basic2DVector<double> Basic2DVectorD;
00258
00259
00260 #endif // GeometryVector_Basic2DVector_h