#ifndef ROOT_Math_GenVector_Rotation3D 
#define ROOT_Math_GenVector_Rotation3D  1
#include "Math/GenVector/Cartesian3D.h"
#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/PositionVector3D.h"
#include "Math/GenVector/PxPyPzE4D.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/3DConversions.h"
#include "Math/GenVector/3DDistances.h"
#include "Math/GenVector/Rotation3Dfwd.h"
#include "Math/GenVector/AxisAnglefwd.h"
#include "Math/GenVector/EulerAnglesfwd.h"
#include "Math/GenVector/Quaternionfwd.h"
#include "Math/GenVector/RotationXfwd.h"
#include "Math/GenVector/RotationYfwd.h"
#include "Math/GenVector/RotationZfwd.h"
#include <algorithm>
#include <cassert>
#include <iostream>
namespace ROOT {
namespace Math {
  
class Rotation3D {
public:
   typedef double Scalar;
   enum ERotation3DMatrixIndex {
      kXX = 0, kXY = 1, kXZ = 2
      , kYX = 3, kYY = 4, kYZ = 5
      , kZX = 6, kZY = 7, kZZ = 8
   };
   
   
   Rotation3D();
   
   template<class IT>
   Rotation3D(IT begin, IT end) { SetComponents(begin,end); }
   
   explicit Rotation3D( AxisAngle const   & a ) { gv_detail::convert(a, *this); }
   
   explicit Rotation3D( EulerAngles const & e ) { gv_detail::convert(e, *this); }
   
   explicit Rotation3D( RotationZYX const & e ) { gv_detail::convert(e, *this); }
   
   explicit Rotation3D( Quaternion const  & q ) { gv_detail::convert(q, *this); }
   
   explicit Rotation3D( RotationZ const & r ) { gv_detail::convert(r, *this); }
   explicit Rotation3D( RotationY const & r ) { gv_detail::convert(r, *this); }
   explicit Rotation3D( RotationX const & r ) { gv_detail::convert(r, *this); }
   
   template<class ForeignMatrix>
   explicit Rotation3D(const ForeignMatrix & m) { SetComponents(m); }
   
   template<class ForeignVector>
   Rotation3D(const ForeignVector& v1,
              const ForeignVector& v2,
              const ForeignVector& v3 ) { SetComponents(v1, v2, v3); }
   
   
   Rotation3D(Scalar  xx, Scalar  xy, Scalar  xz,
              Scalar  yx, Scalar  yy, Scalar  yz,
              Scalar  zx, Scalar  zy, Scalar  zz)
   {
      SetComponents (xx, xy, xz, yx, yy, yz, zx, zy, zz);
   }
   
   Rotation3D &
   operator=( AxisAngle const   & a ) { return operator=(Rotation3D(a)); }
   
   Rotation3D &
   operator=( EulerAngles const & e ) { return operator=(Rotation3D(e)); }
   
   Rotation3D &
   operator=( RotationZYX const & r ) { return operator=(Rotation3D(r)); }
   
   Rotation3D &
   operator=( Quaternion const  & q ) {return operator=(Rotation3D(q)); }
   
   Rotation3D &
   operator=( RotationZ const & r ) { return operator=(Rotation3D(r)); }
   Rotation3D &
   operator=( RotationY const & r ) { return operator=(Rotation3D(r)); }
   Rotation3D &
   operator=( RotationX const & r ) { return operator=(Rotation3D(r)); }
   
   template<class ForeignMatrix>
   Rotation3D &
   operator=(const ForeignMatrix & m) { SetComponents(m); return *this; }
   
   void Rectify();
   
   
   template<class ForeignVector>
   void
   SetComponents (const ForeignVector& v1,
                  const ForeignVector& v2,
                  const ForeignVector& v3 ) {
      fM[kXX]=v1.x();  fM[kXY]=v2.x();  fM[kXZ]=v3.x();
      fM[kYX]=v1.y();  fM[kYY]=v2.y();  fM[kYZ]=v3.y();
      fM[kZX]=v1.z();  fM[kZY]=v2.z();  fM[kZZ]=v3.z();
      Rectify();
   }
   
   template<class ForeignVector>
   void
   GetComponents ( ForeignVector& v1,
                   ForeignVector& v2,
                   ForeignVector& v3 ) const {
      v1 = ForeignVector ( fM[kXX], fM[kYX], fM[kZX] );
      v2 = ForeignVector ( fM[kXY], fM[kYY], fM[kZY] );
      v3 = ForeignVector ( fM[kXZ], fM[kYZ], fM[kZZ] );
   }
   
   template<class IT>
   void SetComponents(IT begin, IT end) {
      for (int i = 0; i <9; ++i) { 
         fM[i] = *begin;
         ++begin;  
      }
      assert (end==begin);
   }
   
   template<class IT>
   void GetComponents(IT begin, IT end) const {
      for (int i = 0; i <9; ++i) { 
         *begin = fM[i];
         ++begin; 
      }
      assert (end==begin);
   }
   
   template<class IT>
   void GetComponents(IT begin) const {
      std::copy ( fM, fM+9, begin );
   }
   
   template<class ForeignMatrix>
   void
   SetRotationMatrix (const ForeignMatrix & m) {
      fM[kXX]=m(0,0);  fM[kXY]=m(0,1);  fM[kXZ]=m(0,2);
      fM[kYX]=m(1,0);  fM[kYY]=m(1,1);  fM[kYZ]=m(1,2);
      fM[kZX]=m(2,0);  fM[kZY]=m(2,1);  fM[kZZ]=m(2,2);
   }
   
   template<class ForeignMatrix>
   void
   GetRotationMatrix (ForeignMatrix & m) const {
      m(0,0)=fM[kXX];  m(0,1)=fM[kXY];  m(0,2)=fM[kXZ];
      m(1,0)=fM[kYX];  m(1,1)=fM[kYY];  m(1,2)=fM[kYZ];
      m(2,0)=fM[kZX];  m(2,1)=fM[kZY];  m(2,2)=fM[kZZ];
   }
   
   void
   SetComponents (Scalar  xx, Scalar  xy, Scalar  xz,
                  Scalar  yx, Scalar  yy, Scalar  yz,
                  Scalar  zx, Scalar  zy, Scalar  zz) {
      fM[kXX]=xx;  fM[kXY]=xy;  fM[kXZ]=xz;
      fM[kYX]=yx;  fM[kYY]=yy;  fM[kYZ]=yz;
      fM[kZX]=zx;  fM[kZY]=zy;  fM[kZZ]=zz;
   }
   
   void
   GetComponents (Scalar &xx, Scalar &xy, Scalar &xz,
                  Scalar &yx, Scalar &yy, Scalar &yz,
                  Scalar &zx, Scalar &zy, Scalar &zz) const {
      xx=fM[kXX];  xy=fM[kXY];  xz=fM[kXZ];
      yx=fM[kYX];  yy=fM[kYY];  yz=fM[kYZ];
      zx=fM[kZX];  zy=fM[kZY];  zz=fM[kZZ];
   }
   
   
   template <class CoordSystem, class U>
   DisplacementVector3D<CoordSystem,U>
   operator() (const DisplacementVector3D<CoordSystem,U> & v) const {
      DisplacementVector3D< Cartesian3D<double>,U > xyz;
      xyz.SetXYZ( fM[kXX] * v.X() + fM[kXY] * v.Y() + fM[kXZ] * v.Z() ,
                  fM[kYX] * v.X() + fM[kYY] * v.Y() + fM[kYZ] * v.Z() , 
                  fM[kZX] * v.X() + fM[kZY] * v.Y() + fM[kZZ] * v.Z() );
      return  DisplacementVector3D<CoordSystem,U>( xyz ); 
   }
   
   template <class CoordSystem, class U>
   PositionVector3D<CoordSystem,U>
   operator() (const PositionVector3D<CoordSystem,U> & v) const {
      DisplacementVector3D< Cartesian3D<double>,U > xyz(v);
      DisplacementVector3D< Cartesian3D<double>,U > rxyz = operator()(xyz);
      return PositionVector3D<CoordSystem,U> ( rxyz );
   }
   
   template <class CoordSystem>
   LorentzVector<CoordSystem>
   operator() (const LorentzVector<CoordSystem> & v) const {
      DisplacementVector3D< Cartesian3D<double> > xyz(v.Vect());
      xyz = operator()(xyz);
      LorentzVector< PxPyPzE4D<double> > xyzt (xyz.X(), xyz.Y(), xyz.Z(), v.E());
      return LorentzVector<CoordSystem> ( xyzt );
   }
   
   template <class ForeignVector>
   ForeignVector
   operator() (const  ForeignVector & v) const {
      DisplacementVector3D< Cartesian3D<double> > xyz(v);
      DisplacementVector3D< Cartesian3D<double> > rxyz = operator()(xyz);
      return ForeignVector ( rxyz.X(), rxyz.Y(), rxyz.Z() );
   }
   
   template <class AVector>
   inline
   AVector operator* (const AVector & v) const
   {
      return operator()(v);
   }
   
   void Invert();
   
   Rotation3D Inverse() const { Rotation3D t(*this); t.Invert(); return t; }
   
   
   Rotation3D operator * (const Rotation3D  & r) const { 
   return Rotation3D 
   (  fM[kXX]*r.fM[kXX] + fM[kXY]*r.fM[kYX] + fM[kXZ]*r.fM[kZX]
    , fM[kXX]*r.fM[kXY] + fM[kXY]*r.fM[kYY] + fM[kXZ]*r.fM[kZY]
    , fM[kXX]*r.fM[kXZ] + fM[kXY]*r.fM[kYZ] + fM[kXZ]*r.fM[kZZ]
    
    , fM[kYX]*r.fM[kXX] + fM[kYY]*r.fM[kYX] + fM[kYZ]*r.fM[kZX]
    , fM[kYX]*r.fM[kXY] + fM[kYY]*r.fM[kYY] + fM[kYZ]*r.fM[kZY]
    , fM[kYX]*r.fM[kXZ] + fM[kYY]*r.fM[kYZ] + fM[kYZ]*r.fM[kZZ]
    
    , fM[kZX]*r.fM[kXX] + fM[kZY]*r.fM[kYX] + fM[kZZ]*r.fM[kZX]
    , fM[kZX]*r.fM[kXY] + fM[kZY]*r.fM[kYY] + fM[kZZ]*r.fM[kZY]
    , fM[kZX]*r.fM[kXZ] + fM[kZY]*r.fM[kYZ] + fM[kZZ]*r.fM[kZZ]   );
   }
   
   
    
   Rotation3D operator * (const AxisAngle   & a) const;
   Rotation3D operator * (const EulerAngles & e) const;
   Rotation3D operator * (const Quaternion  & q) const;
   Rotation3D operator * (const RotationZYX & r) const;
   Rotation3D operator * (const RotationX  & rx) const;
   Rotation3D operator * (const RotationY  & ry) const;
   Rotation3D operator * (const RotationZ  & rz) const;
   
   template <class R>
   Rotation3D & operator *= (const R & r) { return *this = (*this)*r; }
   
   bool operator == (const Rotation3D & rhs) const {
      if( fM[0] != rhs.fM[0] )  return false;
      if( fM[1] != rhs.fM[1] )  return false;
      if( fM[2] != rhs.fM[2] )  return false;
      if( fM[3] != rhs.fM[3] )  return false;
      if( fM[4] != rhs.fM[4] )  return false;
      if( fM[5] != rhs.fM[5] )  return false;
      if( fM[6] != rhs.fM[6] )  return false;
      if( fM[7] != rhs.fM[7] )  return false;
      if( fM[8] != rhs.fM[8] )  return false;
      return true;
   }
   bool operator != (const Rotation3D & rhs) const {
      return ! operator==(rhs);
   }
private:
   Scalar fM[9];
};  
template <class R>
inline
typename Rotation3D::Scalar
Distance ( const Rotation3D& r1, const R & r2) {return gv_detail::dist(r1,r2);}
Rotation3D operator* (RotationX const & r1, Rotation3D const & r2);
Rotation3D operator* (RotationY const & r1, Rotation3D const & r2);
Rotation3D operator* (RotationZ const & r1, Rotation3D const & r2);
Rotation3D operator* (RotationX const & r1, RotationY const & r2);
Rotation3D operator* (RotationX const & r1, RotationZ const & r2);
Rotation3D operator* (RotationY const & r1, RotationX const & r2);
Rotation3D operator* (RotationY const & r1, RotationZ const & r2);
Rotation3D operator* (RotationZ const & r1, RotationX const & r2);
Rotation3D operator* (RotationZ const & r1, RotationY const & r2);
  
std::ostream & operator<< (std::ostream & os, const Rotation3D & r);
  
} 
} 
#endif // ROOT_Math_GenVector_Rotation3D 
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.