#ifndef ROOT_Math_GenVector_Cartesian3D
#define ROOT_Math_GenVector_Cartesian3D 1
#ifndef ROOT_Math_GenVector_Polar3Dfwd
#include "Math/GenVector/Polar3Dfwd.h"
#endif
#ifndef ROOT_Math_Math
#include "Math/Math.h"
#endif
#include <limits>
#ifndef ROOT_Math_GenVector_eta
#include "Math/GenVector/eta.h"
#endif
namespace ROOT {
namespace Math {
template <class T = double>
class Cartesian3D {
public :
typedef T Scalar;
Cartesian3D() : fX(0), fY(0), fZ(0) { }
Cartesian3D(Scalar xx, Scalar yy, Scalar zz) : fX(xx), fY(yy), fZ(zz) { }
template <class CoordSystem>
explicit Cartesian3D(const CoordSystem & v)
: fX(v.X()), fY(v.Y()), fZ(v.Z()) { }
Cartesian3D(const Cartesian3D & v) :
fX(v.X()), fY(v.Y()), fZ(v.Z()) { }
Cartesian3D & operator= (const Cartesian3D & v) {
fX = v.x();
fY = v.y();
fZ = v.z();
return *this;
}
void SetCoordinates( const Scalar src[] ) { fX=src[0]; fY=src[1]; fZ=src[2]; }
void GetCoordinates( Scalar dest[] ) const
{ dest[0] = fX; dest[1] = fY; dest[2] = fZ; }
void SetCoordinates(Scalar xx, Scalar yy, Scalar zz) { fX=xx; fY=yy; fZ=zz; }
void GetCoordinates(Scalar& xx, Scalar& yy, Scalar& zz) const {xx=fX; yy=fY; zz=fZ;}
Scalar X() const { return fX;}
Scalar Y() const { return fY;}
Scalar Z() const { return fZ;}
Scalar Mag2() const { return fX*fX + fY*fY + fZ*fZ;}
Scalar Perp2() const { return fX*fX + fY*fY ;}
Scalar Rho() const { return std::sqrt( Perp2());}
Scalar R() const { return std::sqrt( Mag2());}
Scalar Theta() const { return (fX==0 && fY==0 && fZ==0) ?
0 : atan2(Rho(),Z());}
Scalar Phi() const { return (fX==0 && fY==0) ? 0 : atan2(fY,fX);}
Scalar Eta() const {
return Impl::Eta_FromRhoZ ( Rho(),fZ);
}
void SetX(Scalar xx) { fX = xx; }
void SetY(Scalar yy) { fY = yy; }
void SetZ(Scalar zz) { fZ = zz; }
void SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
fX=xx;
fY=yy;
fZ=zz;
}
void Scale(Scalar a) { fX *= a; fY *= a; fZ *= a; }
void Negate() { fX = -fX; fY = -fY; fZ = -fZ; }
template <class CoordSystem>
Cartesian3D & operator = (const CoordSystem & v) {
fX = v.x();
fY = v.y();
fZ = v.z();
return *this;
}
bool operator == (const Cartesian3D & rhs) const {
return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ;
}
bool operator != (const Cartesian3D & rhs) const {return !(operator==(rhs));}
T x() const { return X();}
T y() const { return Y();}
T z() const { return Z(); }
template <class T2>
explicit Cartesian3D( const Polar3D<T2> & v ) : fZ (v.Z())
{
T rho = v.Rho();
fX = rho * std::cos(v.Phi());
fY = rho * std::sin(v.Phi());
}
template <class T2>
Cartesian3D & operator = (const Polar3D<T2> & v)
{
T rho = v.Rho();
fX = rho * std::cos(v.Phi());
fY = rho * std::sin(v.Phi());
fZ = v.Z();
return *this;
}
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
void SetR(Scalar r);
void SetTheta(Scalar theta);
void SetPhi(Scalar phi);
void SetRho(Scalar rho);
void SetEta(Scalar eta);
#endif
private:
T fX;
T fY;
T fZ;
};
}
}
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
#include "Math/GenVector/GenVector_exception.h"
#include "Math/GenVector/CylindricalEta3D.h"
#include "Math/GenVector/Polar3D.h"
namespace ROOT {
namespace Math {
template <class T>
void Cartesian3D<T>::SetR(Scalar r) {
GenVector_exception e("Cartesian3D::SetR() is not supposed to be called");
throw e;
Polar3D<Scalar> v(*this); v.SetR(r); *this = Cartesian3D<Scalar>(v);
}
template <class T>
void Cartesian3D<T>::SetTheta(Scalar theta) {
GenVector_exception e("Cartesian3D::SetTheta() is not supposed to be called");
throw e;
Polar3D<Scalar> v(*this); v.SetTheta(theta); *this = Cartesian3D<Scalar>(v);
}
template <class T>
void Cartesian3D<T>::SetPhi(Scalar phi) {
GenVector_exception e("Cartesian3D::SetPhi() is not supposed to be called");
throw e;
Polar3D<Scalar> v(*this); v.SetPhi(phi); *this = Cartesian3D<Scalar>(v);
}
template <class T>
void Cartesian3D<T>::SetRho(Scalar rho) {
GenVector_exception e("Cartesian3D::SetRho() is not supposed to be called");
throw e;
CylindricalEta3D<Scalar> v(*this); v.SetRho(rho);
*this = Cartesian3D<Scalar>(v);
}
template <class T>
void Cartesian3D<T>::SetEta(Scalar eta) {
GenVector_exception e("Cartesian3D::SetEta() is not supposed to be called");
throw e;
CylindricalEta3D<Scalar> v(*this); v.SetEta(eta);
*this = Cartesian3D<Scalar>(v);
}
}
}
#endif
#endif /* ROOT_Math_GenVector_Cartesian3D */