Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:09

0001 // @(#)root/mathcore:$Id: b12794c790afad19142e34a401af6c233aba446b $
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004  /**********************************************************************
0005   *                                                                    *
0006   * Copyright (c) 2005 , LCG ROOT MathLib Team                         *
0007   *                    & FNAL LCG ROOT Mathlib Team                    *
0008   *                                                                    *
0009   *                                                                    *
0010   **********************************************************************/
0011 
0012 // Header file for class Cartesian2D
0013 //
0014 // Created by: Lorenzo Moneta  at Mon 16 Apr 2007
0015 //
0016 #ifndef ROOT_Math_GenVector_Cartesian2D
0017 #define ROOT_Math_GenVector_Cartesian2D  1
0018 
0019 #include "Math/GenVector/Polar2Dfwd.h"
0020 
0021 #include "Math/Math.h"
0022 
0023 
0024 namespace ROOT {
0025 
0026 namespace Math {
0027 
0028 //__________________________________________________________________________________________
0029    /**
0030        Class describing a 2D cartesian coordinate system
0031        (x, y coordinates)
0032 
0033        @ingroup GenVector
0034 
0035        @sa Overview of the @ref GenVector "physics vector library"
0036    */
0037 
0038 template <class T = double>
0039 class Cartesian2D {
0040 
0041 public :
0042 
0043    typedef T Scalar;
0044 
0045    static constexpr unsigned int Dimension = 2U;
0046 
0047    /**
0048       Default constructor  with x=y=0
0049    */
0050    Cartesian2D() : fX(0.0), fY(0.0)  {  }
0051 
0052    /**
0053       Constructor from x,y  coordinates
0054    */
0055    Cartesian2D(Scalar xx, Scalar yy) : fX(xx), fY(yy) {  }
0056 
0057    /**
0058       Construct from any Vector or coordinate system implementing
0059       X() and Y()
0060    */
0061    template <class CoordSystem>
0062    explicit constexpr Cartesian2D(const CoordSystem & v)
0063       : fX(v.X()), fY(v.Y()) {  }
0064 
0065 
0066    // for g++  3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
0067    // re-implement them ( there is no no need to have them with g++4)
0068    /**
0069       copy constructor
0070     */
0071    Cartesian2D(const Cartesian2D & v) :
0072       fX(v.X()), fY(v.Y())  {  }
0073 
0074    /**
0075       assignment operator
0076     */
0077    Cartesian2D & operator= (const Cartesian2D & v) {
0078       fX = v.X();
0079       fY = v.Y();
0080       return *this;
0081    }
0082 
0083    /**
0084       Set internal data based on 2 Scalar numbers
0085    */
0086    void SetCoordinates(Scalar  xx, Scalar  yy) { fX=xx; fY=yy;  }
0087 
0088    /**
0089       get internal data into 2 Scalar numbers
0090    */
0091    void GetCoordinates(Scalar& xx, Scalar& yy ) const {xx=fX; yy=fY; }
0092 
0093    Scalar X()     const { return fX;}
0094    Scalar Y()     const { return fY;}
0095    Scalar Mag2()  const { return fX*fX + fY*fY; }
0096    Scalar R() const { using std::sqrt; return sqrt(Mag2()); }
0097    Scalar Phi() const { using std::atan2; return (fX == Scalar(0) && fY == Scalar(0)) ? Scalar(0) : atan2(fY, fX); }
0098 
0099    /**
0100        set the x coordinate value keeping y constant
0101    */
0102    void SetX(Scalar a) { fX = a; }
0103 
0104    /**
0105        set the y coordinate value keeping x constant
0106    */
0107    void SetY(Scalar a) { fY = a; }
0108 
0109    /**
0110        set all values using cartesian coordinates
0111    */
0112    void SetXY(Scalar xx, Scalar yy ) {
0113       fX=xx;
0114       fY=yy;
0115    }
0116 
0117    /**
0118       scale the vector by a scalar quantity a
0119    */
0120    void Scale(Scalar a) { fX *= a; fY *= a;  }
0121 
0122    /**
0123       negate the vector
0124    */
0125    void Negate() { fX = -fX; fY = -fY;  }
0126 
0127    /**
0128        rotate by an angle
0129     */
0130    void Rotate(Scalar angle) {
0131       using std::sin;
0132       const Scalar s = sin(angle);
0133       using std::cos;
0134       const Scalar c = cos(angle);
0135       SetCoordinates(c * fX - s * fY, s * fX + c * fY);
0136    }
0137 
0138    /**
0139       Assignment from any class implementing x(),y()
0140       (can assign from any coordinate system)
0141    */
0142    template <class CoordSystem>
0143    Cartesian2D & operator = (const CoordSystem & v) {
0144       fX = v.x();
0145       fY = v.y();
0146       return *this;
0147    }
0148 
0149    /**
0150       Exact equality
0151    */
0152    bool operator == (const Cartesian2D & rhs) const {
0153       return fX == rhs.fX && fY == rhs.fY;
0154    }
0155    bool operator != (const Cartesian2D & rhs) const {return !(operator==(rhs));}
0156 
0157 
0158    // ============= Compatibility section ==================
0159 
0160    // The following make this coordinate system look enough like a CLHEP
0161    // vector that an assignment member template can work with either
0162    Scalar x() const { return X();}
0163    Scalar y() const { return Y();}
0164 
0165    // ============= Overloads for improved speed ==================
0166 
0167    template <class T2>
0168    explicit constexpr Cartesian2D( const Polar2D<T2> & v )
0169    {
0170       const Scalar r = v.R(); // re-using this instead of calling v.X() and v.Y()
0171       // is the speed improvement
0172       using std::cos;
0173       fX = r * cos(v.Phi());
0174       using std::sin;
0175       fY = r * sin(v.Phi());
0176    }
0177    // Technical note:  This works even though only Polar2Dfwd.h is
0178    // included (and in fact, including Polar2D.h would cause circularity
0179    // problems). It works because any program **using** this ctor must itself
0180    // be including Polar2D.h.
0181 
0182    template <class T2>
0183    Cartesian2D & operator = (const Polar2D<T2> & v)
0184    {
0185       const Scalar r = v.R();
0186       using std::cos;
0187       fX             = r * cos(v.Phi());
0188       using std::sin;
0189       fY             = r * sin(v.Phi());
0190       return *this;
0191    }
0192 
0193 
0194 
0195 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0196 
0197    // ====== Set member functions for coordinates in other systems =======
0198 
0199    void SetR(Scalar r);
0200 
0201    void SetPhi(Scalar phi);
0202 
0203 #endif
0204 
0205 
0206 private:
0207 
0208    /**
0209       (Contiguous) data containing the coordinates values x and y
0210    */
0211    T  fX;
0212    T  fY;
0213 
0214 };
0215 
0216 
0217    } // end namespace Math
0218 
0219 } // end namespace ROOT
0220 
0221 
0222 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0223 // need to put here setter methods to resolve nasty cyclical dependencies
0224 // I need to include other coordinate systems only when Cartesian is already defined
0225 // since they depend on it
0226 
0227 #include "Math/GenVector/GenVector_exception.h"
0228 #include "Math/GenVector/Polar2D.h"
0229 
0230 // ====== Set member functions for coordinates in other systems =======
0231 
0232 namespace ROOT {
0233 
0234    namespace Math {
0235 
0236       template <class T>
0237       void Cartesian2D<T>::SetR(Scalar r) {
0238          GenVector_exception e("Cartesian2D::SetR() is not supposed to be called");
0239          throw e;
0240          Polar2D<Scalar> v(*this); v.SetR(r); *this = Cartesian2D<Scalar>(v);
0241       }
0242 
0243 
0244       template <class T>
0245       void Cartesian2D<T>::SetPhi(Scalar phi) {
0246          GenVector_exception e("Cartesian2D::SetPhi() is not supposed to be called");
0247          throw e;
0248          Polar2D<Scalar> v(*this); v.SetPhi(phi); *this = Cartesian2D<Scalar>(v);
0249       }
0250 
0251 
0252 
0253    } // end namespace Math
0254 
0255 } // end namespace ROOT
0256 
0257 #endif
0258 
0259 
0260 
0261 
0262 #endif /* ROOT_Math_GenVector_Cartesian2D  */