Back to home page

EIC code displayed by LXR

 
 

    


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

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