Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
#ifndef GeometryVector_oldBasic2DVector_h
#define GeometryVector_oldBasic2DVector_h

#include "DataFormats/GeometryVector/interface/Phi.h"
#include "DataFormats/GeometryVector/interface/PreciseFloatType.h"
#include "DataFormats/GeometryVector/interface/CoordinateSets.h"
#if (!defined(__CLING__))
#include "DataFormats/Math/interface/SIMDVec.h"
#endif


#include <cmath>
#include <iosfwd>


template < class T> 
class Basic2DVector {
public:
  typedef  Basic2DVector<T> MathVector;

  typedef T    ScalarType;
  typedef Geom::Polar2Cartesian<T>        Polar;

  /** default constructor uses default constructor of T to initialize the 
   *  components. For built-in floating-point types this means initialization 
   * to zero
   */
  Basic2DVector() : theX(0), theY(0) {}

  /// Copy constructor from same type. Should not be needed but for gcc bug 12685
  Basic2DVector( const Basic2DVector & p) : 
    theX(p.x()), theY(p.y()) {}

  /** Explicit constructor from other (possibly unrelated) vector classes 
   *  The only constraint on the argument type is that it has methods
   *  x() and y(), and that these methods return a type convertible to T.
   *  Examples of use are
   *   <BR> construction from a Basic2DVector with different precision
   *   <BR> construction from a coordinate system converter 
   */
  template <class Other> 
  explicit Basic2DVector( const Other& p) : theX(p.x()), theY(p.y()) {}

  /// construct from cartesian coordinates
  Basic2DVector( const T& x, const T& y) : theX(x), theY(y) {}


#if  defined(USE_EXTVECT)
  // constructor from Vec2 or vec4
  template<typename U>
  Basic2DVector(Vec2<U> const& iv) :
    theX(iv[0]), theY(iv[1]) {}
  template<typename U>
  Basic2DVector(Vec4<U> const& iv) :
    theX(iv.arr[0]), theY(iv.arr[1]) {}
#elif  defined(USE_SSEVECT)
  // constructor from Vec2 or vec4
  template<typename U>
  Basic2DVector(mathSSE::Vec2<U> const& iv) :
    theX(iv.arr[0]), theY(iv.arr[1]) {}
  template<typename U>
  Basic2DVector(mathSSE::Vec4<U> const& iv) :
    theX(iv.arr[0]), theY(iv.arr[1]) {}
#endif  

  T operator[](int i) const { return i==0 ?  theX : theY ;}
  T & operator[](int i) { return i==0 ?  theX : theY ;}

  /// Cartesian x coordinate
  T x() const { return theX;}

  /// Cartesian y coordinate
  T y() const { return theY;}

  /// The vector magnitude squared. Equivalent to vec.dot(vec)
  T mag2() const { return theX*theX + theY*theY;}

  /// The vector magnitude. Equivalent to sqrt(vec.mag2())
  T mag() const  { return std::sqrt( mag2());}

  /// Radius, same as mag()
  T r() const    { return mag();}

  /** Azimuthal angle. The value is returned in radians, in the range (-pi,pi].
   *  Same precision as the system atan2(x,y) function.
   *  The return type is Geom::Phi<T>, see it's documentation.
   */ 
  T barePhi() const {return std::atan2(theY,theX);}
  Geom::Phi<T> phi() const {return Geom::Phi<T>(atan2(theY,theX));}

  /** Unit vector parallel to this.
   *  If mag() is zero, a zero vector is returned.
   */
  Basic2DVector unit() const {
    T my_mag = mag();
    return my_mag == 0 ? *this : *this / my_mag;
  }

  /** Operator += with a Basic2DVector of possibly different precision.
   */
  template <class U> 
  Basic2DVector& operator+= ( const Basic2DVector<U>& p) {
    theX += p.x();
    theY += p.y();
    return *this;
  } 

  /** Operator -= with a Basic2DVector of possibly different precision.
   */
  template <class U> 
  Basic2DVector& operator-= ( const Basic2DVector<U>& p) {
    theX -= p.x();
    theY -= p.y();
    return *this;
  } 

  /// Unary minus, returns a vector with components (-x(),-y(),-z())
  Basic2DVector operator-() const { return Basic2DVector(-x(),-y());}

  /// Scaling by a scalar value (multiplication)
  Basic2DVector& operator*= ( const T& t) {
    theX *= t;
    theY *= t;
    return *this;
  } 

  /// Scaling by a scalar value (division)
  Basic2DVector& operator/= ( const T& t) {
    theX /= t;
    theY /= t;
    return *this;
  } 

  /// Scalar product, or "dot" product, with a vector of same type.
  T dot( const Basic2DVector& v) const { return x()*v.x() + y()*v.y();}

  /** Scalar (or dot) product with a vector of different precision.
   *  The product is computed without loss of precision. The type
   *  of the returned scalar is the more precise of the scalar types 
   *  of the two vectors.
   */
  template <class U> 
  typename PreciseFloatType<T,U>::Type dot( const Basic2DVector<U>& v) const { 
    return x()*v.x() + y()*v.y();
  }



  /// Vector product, or "cross" product, with a vector of same type.
  T cross( const Basic2DVector& v) const { return x()*v.y() - y()*v.x();}

  /** Vector (or cross) product with a vector of different precision.
   *  The product is computed without loss of precision. The type
   *  of the returned scalar is the more precise of the scalar types 
   *  of the two vectors.
   */
  template <class U> 
  typename PreciseFloatType<T,U>::Type cross( const Basic2DVector<U>& v) const { 
    return x()*v.y() - y()*v.x();
  }


private:
  T theX;
  T theY;
};


namespace geometryDetails {
  std::ostream & print2D(std::ostream& s, double x, double y);

}

/// simple text output to standard streams
template <class T>
inline std::ostream & operator<<( std::ostream& s, const Basic2DVector<T>& v) {
  return geometryDetails::print2D(s, v.x(),v.y());
}


/// vector sum and subtraction of vectors of possibly different precision
template <class T, class U>
inline Basic2DVector<typename PreciseFloatType<T,U>::Type>
operator+( const Basic2DVector<T>& a, const Basic2DVector<U>& b) {
  typedef Basic2DVector<typename PreciseFloatType<T,U>::Type> RT;
  return RT(a.x()+b.x(), a.y()+b.y());
}

template <class T, class U>
inline Basic2DVector<typename PreciseFloatType<T,U>::Type>
operator-( const Basic2DVector<T>& a, const Basic2DVector<U>& b) {
  typedef Basic2DVector<typename PreciseFloatType<T,U>::Type> RT;
  return RT(a.x()-b.x(), a.y()-b.y());
}




// scalar product of vectors of same precision
template <class T>
inline T operator*( const Basic2DVector<T>& v1, const Basic2DVector<T>& v2) {
  return v1.dot(v2);
}

/// scalar product of vectors of different precision
template <class T, class U>
inline typename PreciseFloatType<T,U>::Type operator*( const Basic2DVector<T>& v1, 
						       const Basic2DVector<U>& v2) {
  return v1.x()*v2.x() + v1.y()*v2.y();
}

/** Multiplication by scalar, does not change the precision of the vector.
 *  The return type is the same as the type of the vector argument.
 */
template <class T, class Scalar>
inline Basic2DVector<T> operator*( const Basic2DVector<T>& v, const Scalar& s) {
  T t = static_cast<T>(s);
  return Basic2DVector<T>(v.x()*t, v.y()*t);
}

/// Same as operator*( Vector, Scalar)
template <class T, class Scalar>
inline Basic2DVector<T> operator*( const Scalar& s, const Basic2DVector<T>& v) {
  T t = static_cast<T>(s);
  return Basic2DVector<T>(v.x()*t, v.y()*t);
}

/** Division by scalar, does not change the precision of the vector.
 *  The return type is the same as the type of the vector argument.
 */
template <class T, class Scalar>
inline Basic2DVector<T> operator/( const Basic2DVector<T>& v, const Scalar& s) {
  T t = static_cast<T>(s);
  return Basic2DVector<T>(v.x()/t, v.y()/t);
}


typedef Basic2DVector<float> Basic2DVectorF;
typedef Basic2DVector<double> Basic2DVectorD;

#endif // GeometryVector_Basic2DVector_h