Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:15

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