Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:28:10

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        @see GenVector
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    constexpr Cartesian2D() noexcept = default;
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       Set internal data based on 2 Scalar numbers
0067    */
0068    void SetCoordinates(Scalar  xx, Scalar  yy) { fX=xx; fY=yy;  }
0069 
0070    /**
0071       get internal data into 2 Scalar numbers
0072    */
0073    void GetCoordinates(Scalar& xx, Scalar& yy ) const {xx=fX; yy=fY; }
0074 
0075    Scalar X()     const { return fX;}
0076    Scalar Y()     const { return fY;}
0077    Scalar Mag2()  const { return fX*fX + fY*fY; }
0078    Scalar R() const { using std::sqrt; return sqrt(Mag2()); }
0079    Scalar Phi() const { using std::atan2; return (fX == Scalar(0) && fY == Scalar(0)) ? Scalar(0) : atan2(fY, fX); }
0080 
0081    /**
0082        set the x coordinate value keeping y constant
0083    */
0084    void SetX(Scalar a) { fX = a; }
0085 
0086    /**
0087        set the y coordinate value keeping x constant
0088    */
0089    void SetY(Scalar a) { fY = a; }
0090 
0091    /**
0092        set all values using cartesian coordinates
0093    */
0094    void SetXY(Scalar xx, Scalar yy ) {
0095       fX=xx;
0096       fY=yy;
0097    }
0098 
0099    /**
0100       scale the vector by a scalar quantity a
0101    */
0102    void Scale(Scalar a) { fX *= a; fY *= a;  }
0103 
0104    /**
0105       negate the vector
0106    */
0107    void Negate() { fX = -fX; fY = -fY;  }
0108 
0109    /**
0110        rotate by an angle
0111     */
0112    void Rotate(Scalar angle) {
0113       using std::sin;
0114       const Scalar s = sin(angle);
0115       using std::cos;
0116       const Scalar c = cos(angle);
0117       SetCoordinates(c * fX - s * fY, s * fX + c * fY);
0118    }
0119 
0120    /**
0121       Assignment from any class implementing x(),y()
0122       (can assign from any coordinate system)
0123    */
0124    template <class CoordSystem>
0125    Cartesian2D & operator = (const CoordSystem & v) {
0126       fX = v.x();
0127       fY = v.y();
0128       return *this;
0129    }
0130 
0131    /**
0132       Exact equality
0133    */
0134    bool operator == (const Cartesian2D & rhs) const {
0135       return fX == rhs.fX && fY == rhs.fY;
0136    }
0137    bool operator != (const Cartesian2D & rhs) const {return !(operator==(rhs));}
0138 
0139 
0140    // ============= Compatibility section ==================
0141 
0142    // The following make this coordinate system look enough like a CLHEP
0143    // vector that an assignment member template can work with either
0144    Scalar x() const { return X();}
0145    Scalar y() const { return Y();}
0146 
0147    // ============= Overloads for improved speed ==================
0148 
0149    template <class T2>
0150    explicit constexpr Cartesian2D( const Polar2D<T2> & v )
0151    {
0152       const Scalar r = v.R(); // re-using this instead of calling v.X() and v.Y()
0153       // is the speed improvement
0154       using std::cos;
0155       fX = r * cos(v.Phi());
0156       using std::sin;
0157       fY = r * sin(v.Phi());
0158    }
0159    // Technical note:  This works even though only Polar2Dfwd.h is
0160    // included (and in fact, including Polar2D.h would cause circularity
0161    // problems). It works because any program **using** this ctor must itself
0162    // be including Polar2D.h.
0163 
0164    template <class T2>
0165    Cartesian2D & operator = (const Polar2D<T2> & v)
0166    {
0167       const Scalar r = v.R();
0168       using std::cos;
0169       fX             = r * cos(v.Phi());
0170       using std::sin;
0171       fY             = r * sin(v.Phi());
0172       return *this;
0173    }
0174 
0175 
0176 
0177 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0178 
0179    // ====== Set member functions for coordinates in other systems =======
0180 
0181    void SetR(Scalar r);
0182 
0183    void SetPhi(Scalar phi);
0184 
0185 #endif
0186 
0187 
0188 private:
0189 
0190    /**
0191       (Contiguous) data containing the coordinates values x and y
0192    */
0193    T fX = 0;
0194    T fY = 0;
0195 };
0196 
0197 
0198    } // end namespace Math
0199 
0200 } // end namespace ROOT
0201 
0202 
0203 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0204 // need to put here setter methods to resolve nasty cyclical dependencies
0205 // I need to include other coordinate systems only when Cartesian is already defined
0206 // since they depend on it
0207 
0208 #include "Math/GenVector/GenVector_exception.h"
0209 #include "Math/GenVector/Polar2D.h"
0210 
0211 // ====== Set member functions for coordinates in other systems =======
0212 
0213 namespace ROOT {
0214 
0215    namespace Math {
0216 
0217       template <class T>
0218       void Cartesian2D<T>::SetR(Scalar r) {
0219          GenVector_exception e("Cartesian2D::SetR() is not supposed to be called");
0220          throw e;
0221          Polar2D<Scalar> v(*this); v.SetR(r); *this = Cartesian2D<Scalar>(v);
0222       }
0223 
0224 
0225       template <class T>
0226       void Cartesian2D<T>::SetPhi(Scalar phi) {
0227          GenVector_exception e("Cartesian2D::SetPhi() is not supposed to be called");
0228          throw e;
0229          Polar2D<Scalar> v(*this); v.SetPhi(phi); *this = Cartesian2D<Scalar>(v);
0230       }
0231 
0232 
0233 
0234    } // end namespace Math
0235 
0236 } // end namespace ROOT
0237 
0238 #endif
0239 
0240 
0241 
0242 
0243 #endif /* ROOT_Math_GenVector_Cartesian2D  */