Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // @(#)root/mathcore:$Id$
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004  /**********************************************************************
0005   *                                                                    *
0006   * Copyright (c) 2005 , LCG ROOT MathLib Team  and                    *
0007   *                      FNAL LCG ROOT MathLib Team                    *
0008   *                                                                    *
0009   *                                                                    *
0010   **********************************************************************/
0011 
0012 // Header file for class Polar2D
0013 //
0014 // Created by: Lorenzo Moneta  at Mon May 30 11:40:03 2005
0015 // Major revamp:  M. Fischler  at Wed Jun  8 2005
0016 //
0017 // Last update: $Id$
0018 //
0019 #ifndef ROOT_Math_GenVector_Polar2D
0020 #define ROOT_Math_GenVector_Polar2D  1
0021 
0022 #include "Math/Math.h"
0023 #include "TMath.h"
0024 
0025 #include "Math/GenVector/etaMax.h"
0026 
0027 
0028 
0029 namespace ROOT {
0030 
0031 namespace Math {
0032 
0033 
0034 //__________________________________________________________________________________________
0035    /**
0036        Class describing a polar 2D coordinate system based on r and phi
0037        Phi is restricted to be in the range [-PI,PI)
0038 
0039        @ingroup GenVector
0040 
0041        @see GenVector
0042    */
0043 
0044 
0045 template <class T>
0046 class Polar2D {
0047 
0048 public :
0049 
0050    typedef T Scalar;
0051    static constexpr unsigned int Dimension = 2U;
0052 
0053    /**
0054       Default constructor with r=1,phi=0
0055    */
0056    constexpr Polar2D() noexcept = default;
0057 
0058    /**
0059       Construct from the polar coordinates:  r and phi
0060    */
0061    Polar2D(T r,T phi) : fR(r), fPhi(phi) { Restrict(); }
0062 
0063    /**
0064       Construct from any Vector or coordinate system implementing
0065       R() and Phi()
0066    */
0067    template <class CoordSystem >
0068    explicit constexpr Polar2D( const CoordSystem & v ) :
0069       fR(v.R() ),  fPhi(v.Phi() )  { Restrict(); }
0070 
0071    /**
0072       Set internal data based on 2 Scalar numbers
0073    */
0074    void SetCoordinates(Scalar r, Scalar  phi)
0075    { fR=r; fPhi=phi; Restrict(); }
0076 
0077    /**
0078       get internal data into 2 Scalar numbers
0079    */
0080    void GetCoordinates(Scalar& r, Scalar& phi) const {r=fR; phi=fPhi;}
0081 
0082 
0083    Scalar R()     const { return fR;}
0084    Scalar Phi()   const { return fPhi; }
0085    Scalar X() const { using std::cos; return fR * cos(fPhi); }
0086    Scalar Y() const { using std::sin; return fR * sin(fPhi); }
0087    Scalar Mag2()  const { return fR*fR;}
0088 
0089 
0090    // setters (only for data members)
0091 
0092 
0093    /**
0094        set the r coordinate value keeping phi constant
0095    */
0096    void SetR(const T & r) {
0097       fR = r;
0098    }
0099 
0100 
0101    /**
0102        set the phi coordinate value keeping r constant
0103    */
0104    void SetPhi(const T & phi) {
0105       fPhi = phi;
0106       Restrict();
0107    }
0108 
0109    /**
0110        set all values using cartesian coordinates
0111    */
0112    void SetXY(Scalar a, Scalar b);
0113 
0114 
0115 private:
0116    inline static double pi() { return TMath::Pi(); }
0117 
0118    /**
0119       restrict abgle hi to be between -PI and PI
0120     */
0121    inline void Restrict() {
0122       using std::floor;
0123       if (fPhi <= -pi() || fPhi > pi()) fPhi = fPhi - floor(fPhi / (2 * pi()) + .5) * 2 * pi();
0124    }
0125 
0126 public:
0127 
0128    /**
0129        scale by a scalar quantity - for polar coordinates r changes
0130    */
0131    void Scale (T a) {
0132       if (a < 0) {
0133          Negate();
0134          a = -a;
0135       }
0136       // angles do not change when scaling by a positive quantity
0137       fR *= a;
0138    }
0139 
0140    /**
0141       negate the vector
0142    */
0143    void Negate ( ) {
0144       fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
0145    }
0146 
0147    /**
0148       rotate the vector
0149     */
0150    void Rotate(T angle) {
0151       fPhi += angle;
0152       Restrict();
0153    }
0154 
0155    // assignment operators
0156    /**
0157       generic assignment operator from any coordinate system
0158    */
0159    template <class CoordSystem >
0160    Polar2D & operator= ( const CoordSystem & c ) {
0161       fR     = c.R();
0162       fPhi   = c.Phi();
0163       return *this;
0164    }
0165 
0166    /**
0167       Exact equality
0168    */
0169    bool operator==(const Polar2D & rhs) const {
0170       return fR == rhs.fR && fPhi == rhs.fPhi;
0171    }
0172    bool operator!= (const Polar2D & rhs) const {return !(operator==(rhs));}
0173 
0174 
0175    // ============= Compatibility section ==================
0176 
0177    // The following make this coordinate system look enough like a CLHEP
0178    // vector that an assignment member template can work with either
0179    T x() const { return X();}
0180    T y() const { return Y();}
0181 
0182    // ============= Specializations for improved speed ==================
0183 
0184    // (none)
0185 
0186 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0187 
0188    // ====== Set member functions for coordinates in other systems =======
0189 
0190    void SetX(Scalar a);
0191 
0192    void SetY(Scalar a);
0193 
0194 #endif
0195 
0196 private:
0197    T fR = 1.;
0198    T fPhi = 0.;
0199 };
0200 
0201 
0202    } // end namespace Math
0203 
0204 } // end namespace ROOT
0205 
0206 
0207 // move implementations here to avoid circle dependencies
0208 
0209 #include "Math/GenVector/Cartesian2D.h"
0210 
0211 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0212 #include "Math/GenVector/GenVector_exception.h"
0213 #endif
0214 
0215 namespace ROOT {
0216 
0217    namespace Math {
0218 
0219 template <class T>
0220 void Polar2D<T>::SetXY(Scalar a, Scalar b) {
0221    *this = Cartesian2D<Scalar>(a, b);
0222 }
0223 
0224 
0225 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0226 
0227 
0228 // ====== Set member functions for coordinates in other systems =======
0229 
0230       template <class T>
0231       void Polar2D<T>::SetX(Scalar a) {
0232          GenVector_exception e("Polar2D::SetX() is not supposed to be called");
0233          throw e;
0234          Cartesian2D<Scalar> v(*this); v.SetX(a); *this = Polar2D<Scalar>(v);
0235       }
0236       template <class T>
0237       void Polar2D<T>::SetY(Scalar a) {
0238          GenVector_exception e("Polar2D::SetY() is not supposed to be called");
0239          throw e;
0240          Cartesian2D<Scalar> v(*this); v.SetY(a); *this = Polar2D<Scalar>(v);
0241       }
0242 
0243 #endif
0244 
0245 
0246    } // end namespace Math
0247 
0248 } // end namespace ROOT
0249 
0250 
0251 
0252 #endif /* ROOT_Math_GenVector_Polar2D  */