Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10: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                         *
0007   *                                                                    *
0008   *                                                                    *
0009   **********************************************************************/
0010 
0011 // Header file for class PositionVector2D
0012 //
0013 // Created by: Lorenzo Moneta  at Mon Apr 16 2007
0014 //
0015 //
0016 #ifndef ROOT_Math_GenVector_PositionVector2D
0017 #define ROOT_Math_GenVector_PositionVector2D  1
0018 
0019 #include "Math/GenVector/DisplacementVector2D.h"
0020 
0021 #include "Math/GenVector/GenVectorIO.h"
0022 
0023 #include "Math/GenVector/BitReproducible.h"
0024 
0025 #include "Math/GenVector/CoordinateSystemTags.h"
0026 
0027 
0028 namespace ROOT {
0029 
0030    namespace Math {
0031 
0032 
0033 //__________________________________________________________________________________________
0034       /**
0035          Class describing a generic position vector (point) in 2 dimensions.
0036          This class is templated on the type of Coordinate system.
0037          One example is the XYPoint which is a vector based on
0038          double precision x,y data members by using the
0039          ROOT::Math::Cartesian2D<double> Coordinate system.
0040          The class is having also an extra template parameter, the coordinate system tag,
0041          to be able to identify (tag) vector described in different reference coordinate system,
0042          like global or local coordinate systems.
0043 
0044          @ingroup GenVector
0045 
0046          @sa Overview of the @ref GenVector "physics vector library"
0047       */
0048 
0049     template <class CoordSystem, class Tag = DefaultCoordinateSystemTag >
0050     class PositionVector2D {
0051 
0052     public:
0053 
0054        typedef typename CoordSystem::Scalar Scalar;
0055        typedef CoordSystem CoordinateType;
0056        typedef Tag  CoordinateSystemTag;
0057 
0058        // ------ ctors ------
0059 
0060        /**
0061           Default constructor. Construct an empty object with zero values
0062       */
0063 
0064        constexpr PositionVector2D() : fCoordinates() { }
0065 
0066        /**
0067           Construct from three values of type <em>Scalar</em>.
0068           In the case of a XYPoint the values are x,y
0069           In the case of  a polar vector they are r,phi
0070        */
0071        constexpr PositionVector2D(const Scalar & a, const Scalar & b) :
0072           fCoordinates ( a , b)  { }
0073 
0074        /**
0075           Construct from a position vector expressed in different
0076           coordinates, or using a different Scalar type
0077        */
0078        template <class T>
0079        explicit constexpr PositionVector2D( const PositionVector2D<T,Tag> & v) :
0080           fCoordinates ( v.Coordinates() ) { }
0081 
0082        /**
0083           Construct from an arbitrary displacement vector
0084        */
0085        template <class T>
0086        explicit constexpr PositionVector2D( const DisplacementVector2D<T,Tag> & p) :
0087           fCoordinates ( p.Coordinates() ) { }
0088 
0089        /**
0090           Construct from a foreign 2D vector type, for example, Hep2Vector
0091           Precondition: v must implement methods x() and  y()
0092        */
0093        template <class ForeignVector>
0094        explicit constexpr PositionVector2D( const ForeignVector & v) :
0095           fCoordinates ( Cartesian2D<Scalar>( v.x(), v.y() ) ) { }
0096 
0097        // compiler-generated copy ctor and dtor are fine.
0098 
0099        // ------ assignment ------
0100 
0101        /**
0102           Assignment operator from a position vector of arbitrary type
0103        */
0104        template <class OtherCoords>
0105        PositionVector2D & operator=
0106        ( const PositionVector2D<OtherCoords,Tag> & v) {
0107           fCoordinates = v.Coordinates();
0108           return *this;
0109        }
0110 
0111        /**
0112           Assignment operator from a displacement vector of arbitrary type
0113        */
0114        template <class OtherCoords>
0115        PositionVector2D & operator=
0116        ( const DisplacementVector2D<OtherCoords,Tag> & v) {
0117           fCoordinates = v.Coordinates();
0118           return *this;
0119        }
0120 
0121        /**
0122           Assignment from a foreign 2D vector type, for example, Hep2Vector
0123           Precondition: v must implement methods x() and y()
0124        */
0125        template <class ForeignVector>
0126        PositionVector2D & operator= ( const ForeignVector & v) {
0127           SetXY( v.x(),  v.y() );
0128           return *this;
0129        }
0130 
0131        /**
0132           Retrieve a copy of the coordinates object
0133        */
0134        const CoordSystem & Coordinates() const {
0135           return fCoordinates;
0136        }
0137 
0138        /**
0139           Set internal data based on 2 Scalar numbers.
0140           These are for example (x,y) for a cartesian vector or (r,phi) for a polar vector
0141        */
0142        PositionVector2D<CoordSystem, Tag>& SetCoordinates( Scalar a, Scalar b) {
0143           fCoordinates.SetCoordinates(a, b);
0144           return *this;
0145        }
0146 
0147 
0148        /**
0149           get internal data into 2 Scalar numbers.
0150           These are for example (x,y) for a cartesian vector or (r,phi) for a polar vector
0151        */
0152        void GetCoordinates( Scalar& a, Scalar& b) const
0153        { fCoordinates.GetCoordinates(a, b);  }
0154 
0155 
0156        /**
0157           set the values of the vector from the cartesian components (x,y)
0158           (if the vector is held in polar coordinates,
0159           then (x, y) are converted to that form)
0160        */
0161        PositionVector2D<CoordSystem, Tag>& SetXY (Scalar a, Scalar b) {
0162           fCoordinates.SetXY (a,b);
0163           return *this;
0164        }
0165 
0166        // ------------------- Equality -----------------
0167 
0168        /**
0169           Exact equality
0170        */
0171        bool operator==(const PositionVector2D & rhs) const {
0172           return fCoordinates==rhs.fCoordinates;
0173        }
0174        bool operator!= (const PositionVector2D & rhs) const {
0175           return !(operator==(rhs));
0176        }
0177 
0178        // ------ Individual element access, in various coordinate systems ------
0179 
0180        /**
0181           Dimension
0182        */
0183        unsigned int Dimension() const { return fDimension; };
0184 
0185        /**
0186           Cartesian X, converting if necessary from internal coordinate system.
0187        */
0188        Scalar X() const { return fCoordinates.X(); }
0189 
0190        /**
0191           Cartesian Y, converting if necessary from internal coordinate system.
0192        */
0193        Scalar Y() const { return fCoordinates.Y(); }
0194 
0195        /**
0196           Polar R, converting if necessary from internal coordinate system.
0197        */
0198        Scalar R() const { return fCoordinates.R(); }
0199 
0200        /**
0201           Polar phi, converting if necessary from internal coordinate system.
0202        */
0203        Scalar Phi() const { return fCoordinates.Phi(); }
0204 
0205        /**
0206           Magnitute squared ( r^2 in spherical coordinate)
0207        */
0208        Scalar Mag2() const { return fCoordinates.Mag2();}
0209 
0210 
0211        // It is physically meaningless to speak of the unit vector corresponding
0212        // to a point.
0213 
0214        // ------ Setting individual elements present in coordinate system ------
0215 
0216        /**
0217           Change X - Cartesian2D coordinates only
0218        */
0219        PositionVector2D<CoordSystem, Tag>& SetX (Scalar a) {
0220           fCoordinates.SetX(a);
0221           return *this;
0222        }
0223 
0224        /**
0225           Change Y - Cartesian2D coordinates only
0226        */
0227        PositionVector2D<CoordSystem, Tag>& SetY (Scalar a) {
0228           fCoordinates.SetY(a);
0229           return *this;
0230        }
0231 
0232 
0233        /**
0234           Change R - Polar2D coordinates only
0235        */
0236        PositionVector2D<CoordSystem, Tag>& SetR (Scalar a) {
0237           fCoordinates.SetR(a);
0238           return *this;
0239        }
0240 
0241        /**
0242           Change Phi - Polar2D coordinates
0243        */
0244        PositionVector2D<CoordSystem, Tag>& SetPhi (Scalar ang) {
0245           fCoordinates.SetPhi(ang);
0246           return *this;
0247        }
0248 
0249 
0250        // ------ Operations combining two vectors ------
0251        // need to specialize to exclude those with a different tags
0252 
0253        /**
0254         Return the scalar (Dot) product of this with a displacement vector in
0255         any coordinate system, but with the same tag
0256        */
0257        template< class OtherCoords >
0258        Scalar Dot( const  DisplacementVector2D<OtherCoords,Tag> & v) const {
0259           return X()*v.x() + Y()*v.y();
0260        }
0261 
0262 
0263        // The Dot product of a pair of point vectors are physically
0264        // meaningless concepts and thus are defined as private methods
0265 
0266 
0267        /**
0268           Self Addition with a displacement vector.
0269        */
0270        template <class OtherCoords>
0271        PositionVector2D & operator+= (const  DisplacementVector2D<OtherCoords,Tag> & v)
0272        {
0273           SetXY( X() + v.X(), Y() + v.Y() );
0274           return *this;
0275        }
0276 
0277        /**
0278           Self Difference with a displacement vector.
0279        */
0280        template <class OtherCoords>
0281        PositionVector2D & operator-= (const  DisplacementVector2D<OtherCoords,Tag> & v)
0282        {
0283           SetXY(  X() - v.X(), Y() - v.Y() );
0284           return *this;
0285        }
0286 
0287        /**
0288           multiply this vector by a scalar quantity
0289        */
0290        PositionVector2D & operator *= (Scalar a) {
0291           fCoordinates.Scale(a);
0292           return *this;
0293        }
0294 
0295        /**
0296           divide this vector by a scalar quantity
0297        */
0298        PositionVector2D & operator /= (Scalar a) {
0299           fCoordinates.Scale(1/a);
0300           return *this;
0301        }
0302 
0303        // The following methods (v*a and v/a) could instead be free functions.
0304        // They were moved into the class to solve a problem on AIX.
0305        /**
0306           Multiply a vector by a real number
0307        */
0308        PositionVector2D operator * ( Scalar a ) const {
0309           PositionVector2D tmp(*this);
0310           tmp *= a;
0311           return tmp;
0312        }
0313 
0314        /**
0315           Division of a vector with a real number
0316        */
0317        PositionVector2D operator / (Scalar a) const {
0318           PositionVector2D tmp(*this);
0319           tmp /= a;
0320           return tmp;
0321        }
0322 
0323        /**
0324           Rotate by an angle
0325        */
0326        void Rotate( Scalar angle) {
0327           return fCoordinates.Rotate(angle);
0328        }
0329 
0330        // Limited backward name compatibility with CLHEP
0331 
0332        Scalar x()     const { return fCoordinates.X();     }
0333        Scalar y()     const { return fCoordinates.Y();     }
0334        Scalar r()     const { return fCoordinates.R();     }
0335        Scalar phi()   const { return fCoordinates.Phi();   }
0336        Scalar mag2()  const { return fCoordinates.Mag2();  }
0337 
0338     private:
0339 
0340        CoordSystem fCoordinates;
0341        static constexpr unsigned int fDimension = CoordinateType::Dimension;
0342 
0343        // Prohibited methods
0344 
0345        // this should not compile (if from a vector or points with different tag
0346 
0347        template <class OtherCoords, class OtherTag>
0348        explicit constexpr PositionVector2D( const PositionVector2D<OtherCoords, OtherTag> & );
0349 
0350        template <class OtherCoords, class OtherTag>
0351        explicit constexpr PositionVector2D( const DisplacementVector2D<OtherCoords, OtherTag> & );
0352 
0353        template <class OtherCoords, class OtherTag>
0354        PositionVector2D & operator=( const PositionVector2D<OtherCoords, OtherTag> & );
0355 
0356        template <class OtherCoords, class OtherTag>
0357        PositionVector2D & operator=( const DisplacementVector2D<OtherCoords, OtherTag> & );
0358 
0359        template <class OtherCoords, class OtherTag>
0360        PositionVector2D & operator+=(const  DisplacementVector2D<OtherCoords, OtherTag> & );
0361 
0362        template <class OtherCoords, class OtherTag>
0363        PositionVector2D & operator-=(const  DisplacementVector2D<OtherCoords, OtherTag> & );
0364 
0365 //       /**
0366 //          Dot product of two position vectors is inappropriate
0367 //       */
0368 //       template <class T2, class U>
0369 //       PositionVector2D Dot( const PositionVector2D<T2,U> & v) const;
0370 
0371 
0372 
0373     };
0374 
0375 // ---------- PositionVector2D class template ends here ----------------
0376 // ---------------------------------------------------------------------
0377 
0378       /**
0379          Multiplication of a position vector by real number  a*v
0380       */
0381       template <class CoordSystem, class U>
0382       inline
0383       PositionVector2D<CoordSystem>
0384       operator * ( typename PositionVector2D<CoordSystem,U>::Scalar a,
0385                    PositionVector2D<CoordSystem,U> v) {
0386          return v *= a;
0387          // Note - passing v by value and using operator *= may save one
0388          // copy relative to passing v by const ref and creating a temporary.
0389       }
0390 
0391       /**
0392          Difference between two PositionVector2D vectors.
0393          The result is a DisplacementVector2D.
0394          The (coordinate system) type of the returned vector is defined to
0395          be identical to that of the first position vector.
0396       */
0397 
0398       template <class CoordSystem1, class CoordSystem2, class U>
0399       inline
0400       DisplacementVector2D<CoordSystem1,U>
0401       operator-( const PositionVector2D<CoordSystem1,U> & v1,
0402                  const PositionVector2D<CoordSystem2,U> & v2) {
0403          return DisplacementVector2D<CoordSystem1,U>( Cartesian2D<typename CoordSystem1::Scalar>(
0404                                                          v1.X()-v2.X(), v1.Y()-v2.Y() )
0405             );
0406       }
0407 
0408       /**
0409          Addition of a PositionVector2D and a DisplacementVector2D.
0410          The return type is a PositionVector2D,
0411          of the same (coordinate system) type as the input PositionVector2D.
0412       */
0413       template <class CoordSystem1, class CoordSystem2, class U>
0414       inline
0415       PositionVector2D<CoordSystem2,U>
0416       operator+( PositionVector2D<CoordSystem2,U> p1,
0417                  const DisplacementVector2D<CoordSystem1,U>  & v2)        {
0418          return p1 += v2;
0419       }
0420 
0421       /**
0422          Addition of a DisplacementVector2D and a PositionVector2D.
0423          The return type is a PositionVector2D,
0424          of the same (coordinate system) type as the input PositionVector2D.
0425       */
0426       template <class CoordSystem1, class CoordSystem2, class U>
0427       inline
0428       PositionVector2D<CoordSystem2,U>
0429       operator+( DisplacementVector2D<CoordSystem1,U> const & v1,
0430                  PositionVector2D<CoordSystem2,U> p2)        {
0431          return p2 += v1;
0432       }
0433 
0434       /**
0435          Subtraction of a DisplacementVector2D from a PositionVector2D.
0436          The return type is a PositionVector2D,
0437          of the same (coordinate system) type as the input PositionVector2D.
0438       */
0439       template <class CoordSystem1, class CoordSystem2, class U>
0440       inline
0441       PositionVector2D<CoordSystem2,U>
0442       operator-( PositionVector2D<CoordSystem2,U> p1,
0443                  DisplacementVector2D<CoordSystem1,U> const & v2)        {
0444          return p1 -= v2;
0445       }
0446 
0447       // Scaling of a position vector with a real number is not physically meaningful
0448 
0449       // ------------- I/O to/from streams -------------
0450 
0451       template< class char_t, class traits_t, class T, class U >
0452       inline
0453       std::basic_ostream<char_t,traits_t> &
0454       operator << ( std::basic_ostream<char_t,traits_t> & os
0455                     , PositionVector2D<T,U> const & v
0456          )
0457       {
0458          if( !os )  return os;
0459 
0460          typename T::Scalar a, b;
0461          v.GetCoordinates(a, b);
0462 
0463          if( detail::get_manip( os, detail::bitforbit ) )  {
0464             detail::set_manip( os, detail::bitforbit, '\00' );
0465             typedef GenVector_detail::BitReproducible BR;
0466             BR::Output(os, a);
0467             BR::Output(os, b);
0468          }
0469          else  {
0470             os << detail::get_manip( os, detail::open  ) << a
0471                << detail::get_manip( os, detail::sep   ) << b
0472                << detail::get_manip( os, detail::close );
0473          }
0474 
0475          return os;
0476 
0477       }  // op<< <>()
0478 
0479 
0480       template< class char_t, class traits_t, class T, class U >
0481       inline
0482       std::basic_istream<char_t,traits_t> &
0483       operator >> ( std::basic_istream<char_t,traits_t> & is
0484                     , PositionVector2D<T,U> & v
0485          )
0486       {
0487          if( !is )  return is;
0488 
0489          typename T::Scalar a, b;
0490 
0491          if( detail::get_manip( is, detail::bitforbit ) )  {
0492             detail::set_manip( is, detail::bitforbit, '\00' );
0493             typedef GenVector_detail::BitReproducible BR;
0494             BR::Input(is, a);
0495             BR::Input(is, b);
0496          }
0497          else  {
0498             detail::require_delim( is, detail::open  );  is >> a;
0499             detail::require_delim( is, detail::sep   );  is >> b;
0500             detail::require_delim( is, detail::close );
0501          }
0502 
0503          if( is )
0504             v.SetCoordinates(a, b);
0505          return is;
0506 
0507       }  // op>> <>()
0508 
0509 
0510 
0511 
0512    } // namespace Math
0513 
0514 } // namespace ROOT
0515 
0516 
0517 #endif /* ROOT_Math_GenVector_PositionVector2D  */