Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:49:59

0001 #ifndef GeometryVector_newBasic2DVector_h
0002 #define GeometryVector_newBasic2DVector_h
0003 
0004 #include "DataFormats/GeometryVector/interface/Phi.h"
0005 #include "DataFormats/GeometryVector/interface/PreciseFloatType.h"
0006 #include "DataFormats/GeometryVector/interface/CoordinateSets.h"
0007 #include "DataFormats/Math/interface/SSEVec.h"
0008 
0009 #include <cmath>
0010 #include <iosfwd>
0011 
0012 template <class T>
0013 class Basic2DVector {
0014 public:
0015   typedef T ScalarType;
0016   typedef mathSSE::Vec2<T> VectorType;
0017   typedef mathSSE::Vec2<T> MathVector;
0018   typedef Geom::Polar2Cartesian<T> Polar;
0019 
0020   /** default constructor uses default constructor of T to initialize the 
0021    *  components. For built-in floating-point types this means initialization 
0022    * to zero
0023    */
0024   Basic2DVector() {}
0025 
0026   /// Copy constructor from same type. Should not be needed but for gcc bug 12685
0027   Basic2DVector(const Basic2DVector& p) : v(p.v) {}
0028 
0029   template <typename U>
0030   Basic2DVector(const Basic2DVector<U>& p) : v(p.v) {}
0031 
0032   /** Explicit constructor from other (possibly unrelated) vector classes 
0033    *  The only constraint on the argument type is that it has methods
0034    *  x() and y(), and that these methods return a type convertible to T.
0035    *  Examples of use are
0036    *   <BR> construction from a Basic2DVector with different precision
0037    *   <BR> construction from a coordinate system converter 
0038    */
0039   template <class Other>
0040   explicit Basic2DVector(const Other& p) : v(p.x(), p.y()) {}
0041 
0042   /// construct from cartesian coordinates
0043   Basic2DVector(const T& x, const T& y) : v(x, y) {}
0044 
0045   // constructor from Vec2 or vec4
0046   template <typename U>
0047   Basic2DVector(mathSSE::Vec2<U> const& iv) : v(iv) {}
0048   template <typename U>
0049   Basic2DVector(mathSSE::Vec4<U> const& iv) : v(iv.xy()) {}
0050 
0051   MathVector const& mathVector() const { return v; }
0052   MathVector& mathVector() { return v; }
0053 
0054   T operator[](int i) const { return v[i]; }
0055   T& operator[](int i) { return v[i]; }
0056 
0057   /// Cartesian x coordinate
0058   T x() const { return v[0]; }
0059 
0060   /// Cartesian y coordinate
0061   T y() const { return v[1]; }
0062 
0063   /// The vector magnitude squared. Equivalent to vec.dot(vec)
0064   T mag2() const { return ::dot(v, v); }
0065 
0066   /// The vector magnitude. Equivalent to sqrt(vec.mag2())
0067   T mag() const { return std::sqrt(mag2()); }
0068 
0069   /// Radius, same as mag()
0070   T r() const { return mag(); }
0071 
0072   /** Azimuthal angle. The value is returned in radians, in the range (-pi,pi].
0073    *  Same precision as the system atan2(x,y) function.
0074    *  The return type is Geom::Phi<T>, see it's documentation.
0075    */
0076   T barePhi() const { return std::atan2(y(), x()); }
0077   Geom::Phi<T> phi() const { return Geom::Phi<T>(atan2(y(), x())); }
0078 
0079   /** Unit vector parallel to this.
0080    *  If mag() is zero, a zero vector is returned.
0081    */
0082   Basic2DVector unit() const {
0083     T my_mag = mag();
0084     return my_mag == 0 ? *this : *this / my_mag;
0085   }
0086 
0087   /** Operator += with a Basic2DVector of possibly different precision.
0088    */
0089   template <class U>
0090   Basic2DVector& operator+=(const Basic2DVector<U>& p) {
0091     v = v + p.v;
0092     return *this;
0093   }
0094 
0095   /** Operator -= with a Basic2DVector of possibly different precision.
0096    */
0097   template <class U>
0098   Basic2DVector& operator-=(const Basic2DVector<U>& p) {
0099     v = v - p.v;
0100     return *this;
0101   }
0102 
0103   /// Unary minus, returns a vector with components (-x(),-y(),-z())
0104   Basic2DVector operator-() const { return Basic2DVector(-v); }
0105 
0106   /// Scaling by a scalar value (multiplication)
0107   Basic2DVector& operator*=(T t) {
0108     v = v * t;
0109     return *this;
0110   }
0111 
0112   /// Scaling by a scalar value (division)
0113   Basic2DVector& operator/=(T t) {
0114     t = T(1) / t;
0115     v = v * t;
0116     return *this;
0117   }
0118 
0119   /// Scalar product, or "dot" product, with a vector of same type.
0120   T dot(const Basic2DVector& lh) const { return ::dot(v, lh.v); }
0121 
0122   /** Scalar (or dot) product with a vector of different precision.
0123    *  The product is computed without loss of precision. The type
0124    *  of the returned scalar is the more precise of the scalar types 
0125    *  of the two vectors.
0126    */
0127   template <class U>
0128   typename PreciseFloatType<T, U>::Type dot(const Basic2DVector<U>& lh) const {
0129     return Basic2DVector<typename PreciseFloatType<T, U>::Type>(*this).dot(
0130         Basic2DVector<typename PreciseFloatType<T, U>::Type>(lh));
0131   }
0132 
0133   /// Vector product, or "cross" product, with a vector of same type.
0134   T cross(const Basic2DVector& lh) const { return ::cross(v, lh.v); }
0135 
0136   /** Vector (or cross) product with a vector of different precision.
0137    *  The product is computed without loss of precision. The type
0138    *  of the returned scalar is the more precise of the scalar types 
0139    *  of the two vectors.
0140    */
0141   template <class U>
0142   typename PreciseFloatType<T, U>::Type cross(const Basic2DVector<U>& lh) const {
0143     return Basic2DVector<typename PreciseFloatType<T, U>::Type>(*this).cross(
0144         Basic2DVector<typename PreciseFloatType<T, U>::Type>(lh));
0145   }
0146 
0147 public:
0148   mathSSE::Vec2<T> v;
0149 };
0150 
0151 namespace geometryDetails {
0152   std::ostream& print2D(std::ostream& s, double x, double y);
0153 
0154 }
0155 
0156 /// simple text output to standard streams
0157 template <class T>
0158 inline std::ostream& operator<<(std::ostream& s, const Basic2DVector<T>& v) {
0159   return geometryDetails::print2D(s, v.x(), v.y());
0160 }
0161 
0162 /// vector sum and subtraction of vectors of possibly different precision
0163 template <class T>
0164 inline Basic2DVector<T> operator+(const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
0165   return a.v + b.v;
0166 }
0167 template <class T>
0168 inline Basic2DVector<T> operator-(const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
0169   return a.v - b.v;
0170 }
0171 
0172 template <class T, class U>
0173 inline Basic2DVector<typename PreciseFloatType<T, U>::Type> operator+(const Basic2DVector<T>& a,
0174                                                                       const Basic2DVector<U>& b) {
0175   typedef Basic2DVector<typename PreciseFloatType<T, U>::Type> RT;
0176   return RT(a) + RT(b);
0177 }
0178 
0179 template <class T, class U>
0180 inline Basic2DVector<typename PreciseFloatType<T, U>::Type> operator-(const Basic2DVector<T>& a,
0181                                                                       const Basic2DVector<U>& b) {
0182   typedef Basic2DVector<typename PreciseFloatType<T, U>::Type> RT;
0183   return RT(a) - RT(b);
0184 }
0185 
0186 // scalar product of vectors of same precision
0187 template <class T>
0188 inline T operator*(const Basic2DVector<T>& v1, const Basic2DVector<T>& v2) {
0189   return v1.dot(v2);
0190 }
0191 
0192 /// scalar product of vectors of different precision
0193 template <class T, class U>
0194 inline typename PreciseFloatType<T, U>::Type operator*(const Basic2DVector<T>& v1, const Basic2DVector<U>& v2) {
0195   return v1.dot(v2);
0196 }
0197 
0198 /** Multiplication by scalar, does not change the precision of the vector.
0199  *  The return type is the same as the type of the vector argument.
0200  */
0201 template <class T>
0202 inline Basic2DVector<T> operator*(const Basic2DVector<T>& v, T t) {
0203   return v.v * t;
0204 }
0205 
0206 /// Same as operator*( Vector, Scalar)
0207 template <class T>
0208 inline Basic2DVector<T> operator*(T t, const Basic2DVector<T>& v) {
0209   return v.v * t;
0210 }
0211 
0212 template <class T, class Scalar>
0213 inline Basic2DVector<T> operator*(const Basic2DVector<T>& v, const Scalar& s) {
0214   T t = static_cast<T>(s);
0215   return v * t;
0216 }
0217 
0218 /// Same as operator*( Vector, Scalar)
0219 template <class T, class Scalar>
0220 inline Basic2DVector<T> operator*(const Scalar& s, const Basic2DVector<T>& v) {
0221   T t = static_cast<T>(s);
0222   return v * t;
0223 }
0224 
0225 /** Division by scalar, does not change the precision of the vector.
0226  *  The return type is the same as the type of the vector argument.
0227  */
0228 template <class T>
0229 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, T t) {
0230   return v.v / t;
0231 }
0232 
0233 template <class T, class Scalar>
0234 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, const Scalar& s) {
0235   //   T t = static_cast<T>(Scalar(1)/s); return v*t;
0236   T t = static_cast<T>(s);
0237   return v / t;
0238 }
0239 
0240 typedef Basic2DVector<float> Basic2DVectorF;
0241 typedef Basic2DVector<double> Basic2DVectorD;
0242 
0243 #endif  // GeometryVector_Basic2DVector_h