Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:21:57

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 
0024 #include "Math/GenVector/etaMax.h"
0025 
0026 
0027 
0028 namespace ROOT {
0029 
0030 namespace Math {
0031 
0032 
0033 //__________________________________________________________________________________________
0034    /**
0035        Class describing a polar 2D coordinate system based on r and phi
0036        Phi is restricted to be in the range [-PI,PI)
0037 
0038        @ingroup GenVector
0039 
0040        @sa Overview of the @ref GenVector "physics vector library"
0041    */
0042 
0043 
0044 template <class T>
0045 class Polar2D {
0046 
0047 public :
0048 
0049    typedef T Scalar;
0050    static constexpr unsigned int Dimension = 2U;
0051 
0052    /**
0053       Default constructor with r=1,phi=0
0054    */
0055    Polar2D() : fR(1.), fPhi(0) {  }
0056 
0057    /**
0058       Construct from the polar coordinates:  r and phi
0059    */
0060    Polar2D(T r,T phi) : fR(r), fPhi(phi) { Restrict(); }
0061 
0062    /**
0063       Construct from any Vector or coordinate system implementing
0064       R() and Phi()
0065    */
0066    template <class CoordSystem >
0067    explicit constexpr Polar2D( const CoordSystem & v ) :
0068       fR(v.R() ),  fPhi(v.Phi() )  { Restrict(); }
0069 
0070    // for g++  3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
0071    // re-implement them ( there is no no need to have them with g++4)
0072 
0073    /**
0074       copy constructor
0075     */
0076    Polar2D(const Polar2D & v) :
0077       fR(v.R() ),  fPhi(v.Phi() )  {   }
0078 
0079    /**
0080       assignment operator
0081     */
0082    Polar2D & operator= (const Polar2D & v) {
0083       fR     = v.R();
0084       fPhi   = v.Phi();
0085       return *this;
0086    }
0087 
0088 
0089    /**
0090       Set internal data based on 2 Scalar numbers
0091    */
0092    void SetCoordinates(Scalar r, Scalar  phi)
0093    { fR=r; fPhi=phi; Restrict(); }
0094 
0095    /**
0096       get internal data into 2 Scalar numbers
0097    */
0098    void GetCoordinates(Scalar& r, Scalar& phi) const {r=fR; phi=fPhi;}
0099 
0100 
0101    Scalar R()     const { return fR;}
0102    Scalar Phi()   const { return fPhi; }
0103    Scalar X() const { using std::cos; return fR * cos(fPhi); }
0104    Scalar Y() const { using std::sin; return fR * sin(fPhi); }
0105    Scalar Mag2()  const { return fR*fR;}
0106 
0107 
0108    // setters (only for data members)
0109 
0110 
0111    /**
0112        set the r coordinate value keeping phi constant
0113    */
0114    void SetR(const T & r) {
0115       fR = r;
0116    }
0117 
0118 
0119    /**
0120        set the phi coordinate value keeping r constant
0121    */
0122    void SetPhi(const T & phi) {
0123       fPhi = phi;
0124       Restrict();
0125    }
0126 
0127    /**
0128        set all values using cartesian coordinates
0129    */
0130    void SetXY(Scalar a, Scalar b);
0131 
0132 
0133 private:
0134    inline static double pi()  { return M_PI; }
0135 
0136    /**
0137       restrict abgle hi to be between -PI and PI
0138     */
0139    inline void Restrict() {
0140       using std::floor;
0141       if (fPhi <= -pi() || fPhi > pi()) fPhi = fPhi - floor(fPhi / (2 * pi()) + .5) * 2 * pi();
0142    }
0143 
0144 public:
0145 
0146    /**
0147        scale by a scalar quantity - for polar coordinates r changes
0148    */
0149    void Scale (T a) {
0150       if (a < 0) {
0151          Negate();
0152          a = -a;
0153       }
0154       // angles do not change when scaling by a positive quantity
0155       fR *= a;
0156    }
0157 
0158    /**
0159       negate the vector
0160    */
0161    void Negate ( ) {
0162       fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
0163    }
0164 
0165    /**
0166       rotate the vector
0167     */
0168    void Rotate(T angle) {
0169       fPhi += angle;
0170       Restrict();
0171    }
0172 
0173    // assignment operators
0174    /**
0175       generic assignment operator from any coordinate system
0176    */
0177    template <class CoordSystem >
0178    Polar2D & operator= ( const CoordSystem & c ) {
0179       fR     = c.R();
0180       fPhi   = c.Phi();
0181       return *this;
0182    }
0183 
0184    /**
0185       Exact equality
0186    */
0187    bool operator==(const Polar2D & rhs) const {
0188       return fR == rhs.fR && fPhi == rhs.fPhi;
0189    }
0190    bool operator!= (const Polar2D & rhs) const {return !(operator==(rhs));}
0191 
0192 
0193    // ============= Compatibility section ==================
0194 
0195    // The following make this coordinate system look enough like a CLHEP
0196    // vector that an assignment member template can work with either
0197    T x() const { return X();}
0198    T y() const { return Y();}
0199 
0200    // ============= Specializations for improved speed ==================
0201 
0202    // (none)
0203 
0204 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0205 
0206    // ====== Set member functions for coordinates in other systems =======
0207 
0208    void SetX(Scalar a);
0209 
0210    void SetY(Scalar a);
0211 
0212 #endif
0213 
0214 private:
0215    T fR;
0216    T fPhi;
0217 };
0218 
0219 
0220    } // end namespace Math
0221 
0222 } // end namespace ROOT
0223 
0224 
0225 // move implementations here to avoid circle dependencies
0226 
0227 #include "Math/GenVector/Cartesian2D.h"
0228 
0229 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0230 #include "Math/GenVector/GenVector_exception.h"
0231 #endif
0232 
0233 namespace ROOT {
0234 
0235    namespace Math {
0236 
0237 template <class T>
0238 void Polar2D<T>::SetXY(Scalar a, Scalar b) {
0239    *this = Cartesian2D<Scalar>(a, b);
0240 }
0241 
0242 
0243 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0244 
0245 
0246 // ====== Set member functions for coordinates in other systems =======
0247 
0248       template <class T>
0249       void Polar2D<T>::SetX(Scalar a) {
0250          GenVector_exception e("Polar2D::SetX() is not supposed to be called");
0251          throw e;
0252          Cartesian2D<Scalar> v(*this); v.SetX(a); *this = Polar2D<Scalar>(v);
0253       }
0254       template <class T>
0255       void Polar2D<T>::SetY(Scalar a) {
0256          GenVector_exception e("Polar2D::SetY() is not supposed to be called");
0257          throw e;
0258          Cartesian2D<Scalar> v(*this); v.SetY(a); *this = Polar2D<Scalar>(v);
0259       }
0260 
0261 #endif
0262 
0263 
0264    } // end namespace Math
0265 
0266 } // end namespace ROOT
0267 
0268 
0269 
0270 #endif /* ROOT_Math_GenVector_Polar2D  */