Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // @(#)root/mathcore:$Id$
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004  /**********************************************************************
0005   *                                                                    *
0006   * Copyright (c) 2005 , LCG ROOT FNAL MathLib Team                    *
0007   *                                                                    *
0008   *                                                                    *
0009   **********************************************************************/
0010 
0011 // Header file for class RotationZ representing a rotation about the Z axis
0012 //
0013 // Created by: Mark Fischler Mon July 18  2005
0014 //
0015 // Last update: $Id$
0016 //
0017 #ifndef ROOT_Math_GenVector_RotationX
0018 #define ROOT_Math_GenVector_RotationX  1
0019 
0020 
0021 #include "Math/GenVector/Cartesian3D.h"
0022 #include "Math/GenVector/DisplacementVector3D.h"
0023 #include "Math/GenVector/PositionVector3D.h"
0024 #include "Math/GenVector/LorentzVector.h"
0025 #include "Math/GenVector/3DDistances.h"
0026 
0027 #include "Math/GenVector/RotationXfwd.h"
0028 
0029 #include <cmath>
0030 
0031 namespace ROOT {
0032 namespace Math {
0033 
0034 
0035 //__________________________________________________________________________________________
0036    /**
0037       Rotation class representing a 3D rotation about the X axis by the angle of rotation.
0038       For efficiency reason, in addition to the angle, the sine and cosine of the angle are held
0039 
0040       @ingroup GenVector
0041 
0042       @sa Overview of the @ref GenVector "physics vector library"
0043    */
0044 
0045 class RotationX {
0046 
0047 public:
0048 
0049    typedef double Scalar;
0050 
0051 
0052    // ========== Constructors and Assignment =====================
0053 
0054    /**
0055       Default constructor (identity rotation)
0056    */
0057    RotationX() : fAngle(0), fSin(0), fCos(1) { }
0058 
0059    /**
0060       Construct from an angle
0061    */
0062    explicit RotationX( Scalar angle ) :   fAngle(angle),
0063                                           fSin(std::sin(angle)),
0064                                           fCos(std::cos(angle))
0065    {
0066       Rectify();
0067    }
0068 
0069    // The compiler-generated copy ctor, copy assignment, and destructor are OK.
0070 
0071    /**
0072       Rectify makes sure the angle is in (-pi,pi]
0073    */
0074    void Rectify()  {
0075       if ( std::fabs(fAngle) >= M_PI ) {
0076          double x = fAngle / (2.0 * M_PI);
0077          fAngle =  (2.0 * M_PI) * ( x + std::floor(.5-x) );
0078          fSin = std::sin(fAngle);
0079          fCos = std::cos(fAngle);
0080       }
0081    }
0082 
0083    // ======== Components ==============
0084 
0085    /**
0086       Set given the angle.
0087    */
0088    void SetAngle (Scalar angle) {
0089       fSin=std::sin(angle);
0090       fCos=std::cos(angle);
0091       fAngle= angle;
0092       Rectify();
0093    }
0094    void SetComponents (Scalar angle) { SetAngle(angle); }
0095 
0096    /**
0097       Get the angle
0098    */
0099    void GetAngle(Scalar &angle) const { using std::atan2; angle = atan2(fSin, fCos); }
0100    void GetComponents ( Scalar & angle ) const { GetAngle(angle); }
0101 
0102    /**
0103       Angle of rotation
0104    */
0105    Scalar Angle() const { using std::atan2; return atan2(fSin, fCos); }
0106 
0107    /**
0108       Sine or Cosine of the rotation angle
0109    */
0110    Scalar SinAngle () const { return fSin; }
0111    Scalar CosAngle () const { return fCos; }
0112 
0113    // =========== operations ==============
0114 
0115    /**
0116       Rotation operation on a cartesian vector
0117    */
0118 //   typedef  DisplacementVector3D< Cartesian3D<double> > XYZVector;
0119 //   XYZVector operator() (const XYZVector & v) const {
0120 //     return XYZVector ( v.x(), fCos*v.y()-fSin*v.z(), fCos*v.z()+fSin*v.y() );
0121 //   }
0122 
0123 
0124    /**
0125       Rotation operation on a displacement vector in any coordinate system
0126    */
0127    template <class CoordSystem, class U>
0128    DisplacementVector3D<CoordSystem,U>
0129    operator() (const DisplacementVector3D<CoordSystem,U> & v) const {
0130       DisplacementVector3D< Cartesian3D<double>,U > xyz;
0131       xyz.SetXYZ( v.X(), fCos*v.Y()-fSin*v.Z(), fCos*v.Z()+fSin*v.Y() );
0132       return DisplacementVector3D<CoordSystem,U>(xyz);
0133    }
0134 
0135    /**
0136       Rotation operation on a position vector in any coordinate system
0137    */
0138    template <class CoordSystem, class U>
0139    PositionVector3D<CoordSystem, U>
0140    operator() (const PositionVector3D<CoordSystem,U> & v) const {
0141       DisplacementVector3D< Cartesian3D<double>,U > xyz(v);
0142       DisplacementVector3D< Cartesian3D<double>,U > rxyz = operator()(xyz);
0143       return PositionVector3D<CoordSystem,U> ( rxyz );
0144    }
0145 
0146    /**
0147       Rotation operation on a Lorentz vector in any 4D coordinate system
0148    */
0149    template <class CoordSystem>
0150    LorentzVector<CoordSystem>
0151    operator() (const LorentzVector<CoordSystem> & v) const {
0152       DisplacementVector3D< Cartesian3D<double> > xyz(v.Vect());
0153       xyz = operator()(xyz);
0154       LorentzVector< PxPyPzE4D<double> > xyzt (xyz.X(), xyz.Y(), xyz.Z(), v.E());
0155       return LorentzVector<CoordSystem> ( xyzt );
0156    }
0157 
0158    /**
0159       Rotation operation on an arbitrary vector v.
0160       Preconditions:  v must implement methods x(), y(), and z()
0161       and the arbitrary vector type must have a constructor taking (x,y,z)
0162    */
0163    template <class ForeignVector>
0164    ForeignVector
0165    operator() (const  ForeignVector & v) const {
0166       DisplacementVector3D< Cartesian3D<double> > xyz(v);
0167       DisplacementVector3D< Cartesian3D<double> > rxyz = operator()(xyz);
0168       return ForeignVector ( rxyz.X(), rxyz.Y(), rxyz.Z() );
0169    }
0170 
0171    /**
0172       Overload operator * for rotation on a vector
0173    */
0174    template <class AVector>
0175    inline
0176    AVector operator* (const AVector & v) const
0177    {
0178       return operator()(v);
0179    }
0180 
0181    /**
0182       Invert a rotation in place
0183    */
0184    void Invert() { fAngle = -fAngle; fSin = -fSin; }
0185 
0186    /**
0187       Return inverse of  a rotation
0188    */
0189    RotationX Inverse() const { RotationX t(*this); t.Invert(); return t; }
0190 
0191    // ========= Multi-Rotation Operations ===============
0192 
0193    /**
0194       Multiply (combine) two rotations
0195    */
0196    RotationX operator * (const RotationX & r) const {
0197       RotationX ans;
0198       double x   = (fAngle + r.fAngle) / (2.0 * M_PI);
0199       ans.fAngle = (2.0 * M_PI) * ( x + std::floor(.5-x) );
0200       ans.fSin   = fSin*r.fCos + fCos*r.fSin;
0201       ans.fCos   = fCos*r.fCos - fSin*r.fSin;
0202       return ans;
0203    }
0204 
0205    /**
0206       Post-Multiply (on right) by another rotation :  T = T*R
0207    */
0208    RotationX & operator *= (const RotationX & r) { return *this = (*this)*r; }
0209 
0210    /**
0211       Equality/inequality operators
0212    */
0213    bool operator == (const RotationX & rhs) const {
0214       if( fAngle != rhs.fAngle )  return false;
0215       return true;
0216    }
0217    bool operator != (const RotationX & rhs) const {
0218       return ! operator==(rhs);
0219    }
0220 
0221 private:
0222 
0223    Scalar fAngle;   // rotation angle
0224    Scalar fSin;     // sine of the rotation angle
0225    Scalar fCos;     // cosine of the rotation angle
0226 
0227 };  // RotationX
0228 
0229 // ============ Class RotationX ends here ============
0230 
0231 /**
0232    Distance between two rotations
0233  */
0234 template <class R>
0235 inline
0236 typename RotationX::Scalar
0237 Distance ( const RotationX& r1, const R & r2) {return gv_detail::dist(r1,r2);}
0238 
0239 /**
0240    Stream Output and Input
0241  */
0242   // TODO - I/O should be put in the manipulator form
0243 
0244 inline
0245 std::ostream & operator<< (std::ostream & os, const RotationX & r) {
0246   os << " RotationX(" << r.Angle() << ") ";
0247   return os;
0248 }
0249 
0250 
0251 }  // namespace Math
0252 }  // namespace ROOT
0253 
0254 #endif // ROOT_Math_GenVector_RotationX