Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:39:05

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/ExtVec.h"
0008 
0009 #include <cmath>
0010 #include <iosfwd>
0011 
0012 template <class T>
0013 class Basic2DVector {
0014 public:
0015   typedef T ScalarType;
0016   typedef Vec2<T> VectorType;
0017   typedef 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() : v{0, 0} {}
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{T(p.v[0]), T(p.v[1])} {}
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{T(p.x()), T(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   Basic2DVector(MathVector const& iv) : v(iv) {}
0047   template <typename U>
0048   Basic2DVector(Vec2<U> const& iv) : v{iv[0], iv[1]} {}
0049   template <typename U>
0050   Basic2DVector(Vec4<U> const& iv) : v{iv[0], iv[1]} {}
0051 
0052   MathVector const& mathVector() const { return v; }
0053   MathVector& mathVector() { return v; }
0054 
0055   T operator[](int i) const { return v[i]; }
0056   T& operator[](int i) { return v[i]; }
0057 
0058   /// Cartesian x coordinate
0059   T x() const { return v[0]; }
0060 
0061   /// Cartesian y coordinate
0062   T y() const { return v[1]; }
0063 
0064   /// The vector magnitude squared. Equivalent to vec.dot(vec)
0065   T mag2() const { return ::dot(v, v); }
0066 
0067   /// The vector magnitude. Equivalent to sqrt(vec.mag2())
0068   T mag() const { return std::sqrt(mag2()); }
0069 
0070   /// Radius, same as mag()
0071   T r() const { return mag(); }
0072 
0073   /** Azimuthal angle. The value is returned in radians, in the range (-pi,pi].
0074    *  Same precision as the system atan2(x,y) function.
0075    *  The return type is Geom::Phi<T>, see it's documentation.
0076    */
0077   T barePhi() const { return std::atan2(y(), x()); }
0078   Geom::Phi<T> phi() const { return Geom::Phi<T>(atan2(y(), x())); }
0079 
0080   /** Unit vector parallel to this.
0081    *  If mag() is zero, a zero vector is returned.
0082    */
0083   Basic2DVector unit() const {
0084     T my_mag = mag();
0085     return my_mag == 0 ? *this : *this / my_mag;
0086   }
0087 
0088   /** Operator += with a Basic2DVector of possibly different precision.
0089    */
0090   template <class U>
0091   Basic2DVector& operator+=(const Basic2DVector<U>& p) {
0092     v = v + p.v;
0093     return *this;
0094   }
0095 
0096   /** Operator -= with a Basic2DVector of possibly different precision.
0097    */
0098   template <class U>
0099   Basic2DVector& operator-=(const Basic2DVector<U>& p) {
0100     v = v - p.v;
0101     return *this;
0102   }
0103 
0104   /// Unary minus, returns a vector with components (-x(),-y(),-z())
0105   Basic2DVector operator-() const { return Basic2DVector(-v); }
0106 
0107   /// Scaling by a scalar value (multiplication)
0108   Basic2DVector& operator*=(T t) {
0109     v = v * t;
0110     return *this;
0111   }
0112 
0113   /// Scaling by a scalar value (division)
0114   Basic2DVector& operator/=(T t) {
0115     t = T(1) / t;
0116     v = v * t;
0117     return *this;
0118   }
0119 
0120   /// Scalar product, or "dot" product, with a vector of same type.
0121   T dot(const Basic2DVector& lh) const { return ::dot(v, lh.v); }
0122 
0123   /** Scalar (or dot) product with a vector of different precision.
0124    *  The product is computed without loss of precision. The type
0125    *  of the returned scalar is the more precise of the scalar types 
0126    *  of the two vectors.
0127    */
0128   template <class U>
0129   typename PreciseFloatType<T, U>::Type dot(const Basic2DVector<U>& lh) const {
0130     return Basic2DVector<typename PreciseFloatType<T, U>::Type>(*this).dot(
0131         Basic2DVector<typename PreciseFloatType<T, U>::Type>(lh));
0132   }
0133 
0134   /// Vector product, or "cross" product, with a vector of same type.
0135   T cross(const Basic2DVector& lh) const { return ::cross2(v, lh.v); }
0136 
0137   /** Vector (or cross) product with a vector of different precision.
0138    *  The product is computed without loss of precision. The type
0139    *  of the returned scalar is the more precise of the scalar types 
0140    *  of the two vectors.
0141    */
0142   template <class U>
0143   typename PreciseFloatType<T, U>::Type cross(const Basic2DVector<U>& lh) const {
0144     return Basic2DVector<typename PreciseFloatType<T, U>::Type>(*this).cross(
0145         Basic2DVector<typename PreciseFloatType<T, U>::Type>(lh));
0146   }
0147 
0148 public:
0149   Vec2<T> v;
0150 };
0151 
0152 namespace geometryDetails {
0153   std::ostream& print2D(std::ostream& s, double x, double y);
0154 
0155 }
0156 
0157 /// simple text output to standard streams
0158 template <class T>
0159 inline std::ostream& operator<<(std::ostream& s, const Basic2DVector<T>& v) {
0160   return geometryDetails::print2D(s, v.x(), v.y());
0161 }
0162 
0163 /// vector sum and subtraction of vectors of possibly different precision
0164 template <class T>
0165 inline Basic2DVector<T> operator+(const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
0166   return a.v + b.v;
0167 }
0168 template <class T>
0169 inline Basic2DVector<T> operator-(const Basic2DVector<T>& a, const Basic2DVector<T>& b) {
0170   return a.v - b.v;
0171 }
0172 
0173 template <class T, class U>
0174 inline Basic2DVector<typename PreciseFloatType<T, U>::Type> operator+(const Basic2DVector<T>& a,
0175                                                                       const Basic2DVector<U>& b) {
0176   typedef Basic2DVector<typename PreciseFloatType<T, U>::Type> RT;
0177   return RT(a) + RT(b);
0178 }
0179 
0180 template <class T, class U>
0181 inline Basic2DVector<typename PreciseFloatType<T, U>::Type> operator-(const Basic2DVector<T>& a,
0182                                                                       const Basic2DVector<U>& b) {
0183   typedef Basic2DVector<typename PreciseFloatType<T, U>::Type> RT;
0184   return RT(a) - RT(b);
0185 }
0186 
0187 // scalar product of vectors of same precision
0188 template <class T>
0189 inline T operator*(const Basic2DVector<T>& v1, const Basic2DVector<T>& v2) {
0190   return v1.dot(v2);
0191 }
0192 
0193 /// scalar product of vectors of different precision
0194 template <class T, class U>
0195 inline typename PreciseFloatType<T, U>::Type operator*(const Basic2DVector<T>& v1, const Basic2DVector<U>& v2) {
0196   return v1.dot(v2);
0197 }
0198 
0199 /** Multiplication by scalar, does not change the precision of the vector.
0200  *  The return type is the same as the type of the vector argument.
0201  */
0202 template <class T>
0203 inline Basic2DVector<T> operator*(const Basic2DVector<T>& v, T t) {
0204   return v.v * t;
0205 }
0206 
0207 /// Same as operator*( Vector, Scalar)
0208 template <class T>
0209 inline Basic2DVector<T> operator*(T t, const Basic2DVector<T>& v) {
0210   return v.v * t;
0211 }
0212 
0213 template <class T, class Scalar>
0214 inline Basic2DVector<T> operator*(const Basic2DVector<T>& v, const Scalar& s) {
0215   T t = static_cast<T>(s);
0216   return v * t;
0217 }
0218 
0219 /// Same as operator*( Vector, Scalar)
0220 template <class T, class Scalar>
0221 inline Basic2DVector<T> operator*(const Scalar& s, const Basic2DVector<T>& v) {
0222   T t = static_cast<T>(s);
0223   return v * t;
0224 }
0225 
0226 /** Division by scalar, does not change the precision of the vector.
0227  *  The return type is the same as the type of the vector argument.
0228  */
0229 template <class T>
0230 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, T t) {
0231   return v.v / t;
0232 }
0233 
0234 template <class T, class Scalar>
0235 inline Basic2DVector<T> operator/(const Basic2DVector<T>& v, const Scalar& s) {
0236   //   T t = static_cast<T>(Scalar(1)/s); return v*t;
0237   T t = static_cast<T>(s);
0238   return v / t;
0239 }
0240 
0241 typedef Basic2DVector<float> Basic2DVectorF;
0242 typedef Basic2DVector<double> Basic2DVectorD;
0243 
0244 #endif  // GeometryVector_Basic2DVector_h