#ifndef ROOT_Math_GenVector_RotationZYX
#define ROOT_Math_GenVector_RotationZYX 1
#ifndef ROOT_Math_Math
#include "Math/Math.h"
#endif
#ifndef ROOT_Math_GenVector_Rotation3D
#include "Math/GenVector/Rotation3D.h"
#endif
#ifndef ROOT_Math_GenVector_DisplacementVector3D
#include "Math/GenVector/DisplacementVector3D.h"
#endif
#ifndef ROOT_Math_GenVector_PositionVector3D
#include "Math/GenVector/PositionVector3D.h"
#endif
#ifndef ROOT_Math_GenVector_LorentzVector
#include "Math/GenVector/LorentzVector.h"
#endif
#ifndef ROOT_Math_GenVector_3DConversions
#include "Math/GenVector/3DConversions.h"
#endif
#include <algorithm>
#include <cassert>
#include <iostream>
namespace ROOT {
namespace Math {
class RotationZYX {
public:
typedef double Scalar;
RotationZYX() : fPhi(0.0), fTheta(0.0), fPsi(0.0) { }
RotationZYX( Scalar phi, Scalar theta, Scalar psi ) :
fPhi(phi), fTheta(theta), fPsi(psi)
{Rectify();}
template<class IT>
RotationZYX(IT begin, IT end) { SetComponents(begin,end); }
void Rectify();
template <class OtherRotation>
explicit RotationZYX(const OtherRotation & r) {gv_detail::convert(r,*this);}
template <class OtherRotation>
RotationZYX & operator=( OtherRotation const & r ) {
gv_detail::convert(r,*this);
return *this;
}
template<class IT>
void SetComponents(IT begin, IT end) {
(void)end;
fPhi = *begin++;
fTheta = *begin++;
fPsi = *begin++;
assert(begin == end);
Rectify();
}
template<class IT>
void GetComponents(IT begin, IT end) const {
(void)end;
*begin++ = fPhi;
*begin++ = fTheta;
*begin++ = fPsi;
assert(begin == end);
}
template<class IT>
void GetComponents(IT begin) const {
*begin++ = fPhi;
*begin++ = fTheta;
*begin = fPsi;
}
void SetComponents(Scalar phi, Scalar theta, Scalar psi) {
fPhi=phi; fTheta=theta; fPsi=psi;
Rectify();
}
void GetComponents(Scalar & phi, Scalar & theta, Scalar & psi) const {
phi=fPhi; theta=fTheta; psi=fPsi;
}
void SetPhi(Scalar phi) { fPhi=phi; Rectify(); }
Scalar Phi() const { return fPhi; }
void SetTheta(Scalar theta) { fTheta=theta; Rectify(); }
Scalar Theta() const { return fTheta; }
void SetPsi(Scalar psi) { fPsi=psi; Rectify(); }
Scalar Psi() const { return fPsi; }
template <class CoordSystem, class U>
DisplacementVector3D<CoordSystem,U>
operator() (const DisplacementVector3D<CoordSystem,U> & v) const {
return Rotation3D(*this) ( v );
}
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();
RotationZYX Inverse() const {
RotationZYX r(*this);
r.Invert();
return r;
}
RotationZYX operator * (const RotationZYX & e) const;
RotationZYX operator * (const Rotation3D & r) const;
RotationZYX operator * (const AxisAngle & a) const;
RotationZYX operator * (const Quaternion & q) const;
RotationZYX operator * (const EulerAngles & q) const;
RotationZYX operator * (const RotationX & rx) const;
RotationZYX operator * (const RotationY & ry) const;
RotationZYX operator * (const RotationZ & rz) const;
template <class R>
RotationZYX & operator *= (const R & r) { return *this = (*this)*r; }
template <class R>
Scalar Distance ( const R & r ) const {return gv_detail::dist(*this,r);}
bool operator == (const RotationZYX & rhs) const {
if( fPhi != rhs.fPhi ) return false;
if( fTheta != rhs.fTheta ) return false;
if( fPsi != rhs.fPsi ) return false;
return true;
}
bool operator != (const RotationZYX & rhs) const {
return ! operator==(rhs);
}
private:
double fPhi;
double fTheta;
double fPsi;
static double Pi() { return M_PI; }
};
template <class R>
inline
typename RotationZYX::Scalar
Distance ( const RotationZYX& r1, const R & r2) {return gv_detail::dist(r1,r2);}
RotationZYX operator* (RotationX const & r1, RotationZYX const & r2);
RotationZYX operator* (RotationY const & r1, RotationZYX const & r2);
RotationZYX operator* (RotationZ const & r1, RotationZYX const & r2);
std::ostream & operator<< (std::ostream & os, const RotationZYX & e);
}
}
#endif // ROOT_Math_GenVector_RotationZYX