#ifndef ROOT_Math_GenVector_AxisAngle 
#define ROOT_Math_GenVector_AxisAngle  1
#include "Math/GenVector/Rotation3D.h"
#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/PositionVector3D.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/3DConversions.h"
#include <algorithm>
#include <cassert>
namespace ROOT {
namespace Math {
  
class AxisAngle {
public:
   typedef double Scalar;
   
   typedef DisplacementVector3D<Cartesian3D<Scalar> > AxisVector;
   
   AxisAngle() : fAxis(0,0,1), fAngle(0) { }
   
   template<class AnyVector>
   AxisAngle(const AnyVector & v, Scalar angle) :
      fAxis(v.unit()), fAngle(angle) { }
   
   template<class IT>
   AxisAngle(IT begin, IT end) { SetComponents(begin,end); }
   
   
   void Rectify();
   
   
   template <class OtherRotation> 
   explicit AxisAngle(const OtherRotation & r) {gv_detail::convert(r,*this);}
   
   template <class OtherRotation> 
   AxisAngle & operator=( OtherRotation const  & r ) { 
      gv_detail::convert(r,*this);
      return *this;
   }
   
   
   template<class IT>
   void SetComponents(IT begin, IT end) {
      IT a = begin; IT b = ++begin; IT c = ++begin;
      fAxis.SetCoordinates(*a,*b,*c);
      fAngle = *(++begin); 
      assert (++begin==end);
      
      double tot = fAxis.R();
      if (tot >  0) fAxis /= tot;
   }
   
   template<class IT>
   void GetComponents(IT begin, IT end) const {
      IT a = begin; IT b = ++begin; IT c = ++begin;
      fAxis.GetCoordinates(*a,*b,*c);
      *(++begin) = fAngle;  
      assert (++begin==end);
   }
   
   template<class IT>
   void GetComponents(IT begin) const {
      double ax,ay,az = 0;
      fAxis.GetCoordinates(ax,ay,az);
      *begin++ = ax; 
      *begin++ = ay; 
      *begin++ = az; 
      *begin = fAngle;
   }
   
   template<class AnyVector>
   void SetComponents(const AnyVector & v, Scalar angle) {
      fAxis=v.unit();
      fAngle=angle;
   }
   
   template<class AnyVector>
   void GetComponents(AnyVector & axis, Scalar & angle) const {
      axis  = fAxis;
      angle = fAngle;
   }
   
   AxisVector Axis() const { return fAxis; }
   
   Scalar Angle() const { return fAngle; }
   
   
   typedef  DisplacementVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag > XYZVector; 
   XYZVector operator() (const XYZVector & v) const;
   
   template <class CoordSystem, class Tag>
   DisplacementVector3D<CoordSystem, Tag>
   operator() (const DisplacementVector3D<CoordSystem, Tag> & v) const {
      DisplacementVector3D< Cartesian3D<double> > xyz(v.X(), v.Y(), v.Z());
      DisplacementVector3D< Cartesian3D<double> > rxyz = operator()(xyz);
      DisplacementVector3D< CoordSystem, Tag > vNew;
      vNew.SetXYZ( rxyz.X(), rxyz.Y(), rxyz.Z() ); 
      return vNew; 
   }
   
   template <class CoordSystem, class Tag>
   PositionVector3D<CoordSystem, Tag>
   operator() (const PositionVector3D<CoordSystem,Tag> & p) const {
      DisplacementVector3D< Cartesian3D<double>,Tag > xyz(p);
      DisplacementVector3D< Cartesian3D<double>,Tag > rxyz = operator()(xyz);
      return PositionVector3D<CoordSystem,Tag> ( 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() { fAngle = -fAngle; }
   
   AxisAngle Inverse() const { AxisAngle result(*this); result.Invert(); return result; }
   
   
   AxisAngle operator * (const Rotation3D  & r) const;
   AxisAngle operator * (const AxisAngle   & a) const;
   AxisAngle operator * (const EulerAngles & e) const;
   AxisAngle operator * (const Quaternion  & q) const;
   AxisAngle operator * (const RotationZYX & r) const;
   AxisAngle operator * (const RotationX  & rx) const;
   AxisAngle operator * (const RotationY  & ry) const;
   AxisAngle operator * (const RotationZ  & rz) const;
   
   template <class R>
   AxisAngle & 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 AxisAngle & rhs) const {
      if( fAxis  != rhs.fAxis  )  return false;
      if( fAngle != rhs.fAngle )  return false;
      return true;
   }
   bool operator != (const AxisAngle & rhs) const {
      return ! operator==(rhs);
   }
private:
   AxisVector  fAxis;
   Scalar      fAngle;
   void RectifyAngle();
   static double Pi() { return 3.14159265358979323; }
};  
template <class R>
inline
typename AxisAngle::Scalar
Distance ( const AxisAngle& r1, const R & r2) {return gv_detail::dist(r1,r2);}
AxisAngle operator* (RotationX const & r1, AxisAngle const & r2);
AxisAngle operator* (RotationY const & r1, AxisAngle const & r2);
AxisAngle operator* (RotationZ const & r1, AxisAngle const & r2);
  
std::ostream & operator<< (std::ostream & os, const AxisAngle & a);
} 
} 
#endif /* ROOT_Math_GenVector_AxisAngle  */
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.