#ifndef ROOT_TQuaternion
#define ROOT_TQuaternion
#include "TVector3.h"
class TQuaternion : public TObject {
public:
TQuaternion(Double_t real = 0, Double_t X = 0, Double_t Y = 0, Double_t Z = 0);
TQuaternion(const TVector3 & vector, Double_t real = 0);
TQuaternion(const Double_t *);
TQuaternion(const Float_t *);
TQuaternion(const TQuaternion &);
virtual ~TQuaternion();
Double_t operator () (int) const;
inline Double_t operator [] (int) const;
Double_t & operator () (int);
inline Double_t & operator [] (int);
inline TQuaternion& SetRXYZ(Double_t r,Double_t x,Double_t y,Double_t z);
inline TQuaternion& SetRV(Double_t r, TVector3& vect);
TQuaternion& SetAxisQAngle(TVector3& v,Double_t QAngle);
Double_t GetQAngle() const;
TQuaternion& SetQAngle(Double_t angle);
inline void GetRXYZ(Double_t *carray) const;
inline void GetRXYZ(Float_t *carray) const;
inline TQuaternion& operator=(Double_t r);
inline Bool_t operator == (Double_t r) const;
inline Bool_t operator != (Double_t r) const;
inline TQuaternion& operator+=(Double_t real);
inline TQuaternion& operator-=(Double_t real);
inline TQuaternion& operator*=(Double_t real);
inline TQuaternion& operator/=(Double_t real);
TQuaternion operator*(Double_t real) const;
TQuaternion operator+(Double_t real) const;
TQuaternion operator-(Double_t real) const;
TQuaternion operator/(Double_t real) const;
inline TQuaternion& operator=(const TVector3& );
inline Bool_t operator == (const TVector3&) const;
inline Bool_t operator != (const TVector3&) const;
inline TQuaternion& operator+=(const TVector3 &vector);
inline TQuaternion& operator-=(const TVector3 &vector);
TQuaternion& MultiplyLeft(const TVector3 &vector);
TQuaternion& operator*=(const TVector3 &vector);
TQuaternion& DivideLeft(const TVector3 &vector);
TQuaternion& operator/=(const TVector3 &vector);
TQuaternion operator+(const TVector3 &vector) const;
TQuaternion operator-(const TVector3 &vector) const;
TQuaternion LeftProduct(const TVector3 &vector) const;
TQuaternion operator*(const TVector3 &vector) const;
TQuaternion LeftQuotient(const TVector3 &vector) const;
TQuaternion operator/(const TVector3 &vector) const;
inline TQuaternion& operator=(const TQuaternion& );
inline Bool_t operator == (const TQuaternion&) const;
inline Bool_t operator != (const TQuaternion&) const;
inline TQuaternion& operator+=(const TQuaternion &quaternion);
inline TQuaternion& operator-=(const TQuaternion &quaternion);
TQuaternion& MultiplyLeft(const TQuaternion &quaternion);
TQuaternion& operator*=(const TQuaternion &quaternion);
TQuaternion& DivideLeft(const TQuaternion &quaternion);
TQuaternion& operator/=(const TQuaternion &quaternion);
TQuaternion operator+(const TQuaternion &quaternion) const;
TQuaternion operator-(const TQuaternion &quaternion) const;
TQuaternion LeftProduct(const TQuaternion &quaternion) const;
TQuaternion operator*(const TQuaternion &quaternion) const;
TQuaternion LeftQuotient(const TQuaternion &quaternion) const;
TQuaternion operator/(const TQuaternion &quaternion) const;
inline Double_t Norm() const;
inline Double_t Norm2() const;
Double_t QMag() const { return Norm(); }
Double_t QMag2() const { return Norm2(); }
inline TQuaternion& Normalize();
inline TQuaternion operator - () const;
inline TQuaternion Conjugate() const;
TQuaternion Invert() const;
void Rotate(TVector3& vect) const;
TVector3 Rotation(const TVector3& vect) const;
void Print(Option_t* option="") const;
Double_t fRealPart;
TVector3 fVectorPart;
ClassDef(TQuaternion,1)
};
inline TQuaternion& TQuaternion::SetRXYZ(Double_t r,Double_t x,Double_t y,Double_t z) {
fRealPart = r;
fVectorPart.SetXYZ(x,y,z);
return (*this);
}
inline TQuaternion& TQuaternion::SetRV(Double_t r, TVector3& vect) {
fRealPart = r;
fVectorPart= vect;
return (*this);
}
inline void TQuaternion::GetRXYZ(Double_t *carray) const {
fVectorPart.GetXYZ(carray+1);
carray[0] = fRealPart;
}
inline void TQuaternion::GetRXYZ(Float_t *carray) const {
fVectorPart.GetXYZ(carray+1);
carray[0] = (Float_t) fRealPart;
}
inline Double_t & TQuaternion::operator[] (int i) { return operator()(i); }
inline Double_t TQuaternion::operator[] (int i) const { return operator()(i); }
inline Bool_t TQuaternion::operator == (Double_t r) const {
return (fVectorPart.Mag2()==0 && fRealPart == r) ? kTRUE : kFALSE;
}
inline Bool_t TQuaternion::operator != (Double_t r) const {
return (fVectorPart.Mag2()!=0 || fRealPart != r) ? kTRUE : kFALSE;
}
inline TQuaternion& TQuaternion::operator=(Double_t r) {
fRealPart = r;
fVectorPart.SetXYZ(0,0,0);
return (*this);
}
inline TQuaternion& TQuaternion::operator+=(Double_t real) {
fRealPart += real;
return (*this);
}
inline TQuaternion& TQuaternion::operator-=(Double_t real) {
fRealPart -= real;
return (*this);
}
inline TQuaternion& TQuaternion::operator*=(Double_t real) {
fRealPart *= real;
fVectorPart *= real;
return (*this);
}
inline TQuaternion& TQuaternion::operator/=(Double_t real) {
if (real!=0) {
fRealPart /= real;
fVectorPart.SetX(fVectorPart.x()/real);
fVectorPart.SetY(fVectorPart.y()/real);
fVectorPart.SetZ(fVectorPart.z()/real);
} else {
Error("operator/=()(Double_t)", "bad value (%f) ignored",real);
}
return (*this);
}
TQuaternion operator + (Double_t r, const TQuaternion & q);
TQuaternion operator - (Double_t r, const TQuaternion & q);
TQuaternion operator * (Double_t r, const TQuaternion & q);
TQuaternion operator / (Double_t r, const TQuaternion & q);
inline Bool_t TQuaternion::operator == (const TVector3& V) const {
return (fVectorPart == V && fRealPart == 0) ? kTRUE : kFALSE;
}
inline Bool_t TQuaternion::operator != (const TVector3& V) const {
return (fVectorPart != V || fRealPart != 0) ? kTRUE : kFALSE;
}
inline TQuaternion& TQuaternion::operator=(const TVector3& vect) {
fRealPart = 0;
fVectorPart.SetXYZ(vect.X(),vect.Y(),vect.Z());
return *this;
}
inline TQuaternion& TQuaternion::operator+=(const TVector3 &vect) {
fVectorPart += vect;
return (*this);
}
inline TQuaternion& TQuaternion::operator-=(const TVector3 &vect) {
fVectorPart -= vect;
return (*this);
}
TQuaternion operator + (const TVector3 &V, const TQuaternion &Q);
TQuaternion operator - (const TVector3 &V, const TQuaternion &Q);
TQuaternion operator * (const TVector3 &V, const TQuaternion &Q);
TQuaternion operator / (const TVector3 &V, const TQuaternion &Q);
inline Bool_t TQuaternion::operator == (const TQuaternion& Q) const {
return (fVectorPart == Q.fVectorPart && fRealPart == Q.fRealPart) ? kTRUE : kFALSE;
}
inline Bool_t TQuaternion::operator != (const TQuaternion& Q) const {
return (fVectorPart != Q.fVectorPart || fRealPart != Q.fRealPart) ? kTRUE : kFALSE;
}
inline TQuaternion& TQuaternion::operator=(const TQuaternion& quat) {
fRealPart = quat.fRealPart;
fVectorPart.SetXYZ(quat.fVectorPart.X(),quat.fVectorPart.Y(),quat.fVectorPart.Z());
return (*this);
}
inline TQuaternion& TQuaternion::operator+=(const TQuaternion &quaternion) {
fVectorPart += quaternion.fVectorPart;
fRealPart += quaternion.fRealPart;
return (*this);
}
inline TQuaternion& TQuaternion::operator-=(const TQuaternion &quaternion) {
fVectorPart -= quaternion.fVectorPart;
fRealPart -= quaternion.fRealPart;
return (*this);
}
inline TQuaternion TQuaternion::operator+(const TQuaternion &quaternion) const {
return TQuaternion(fVectorPart+quaternion.fVectorPart, fRealPart+quaternion.fRealPart);
}
inline TQuaternion TQuaternion::operator-(const TQuaternion &quaternion) const {
return TQuaternion(fVectorPart-quaternion.fVectorPart, fRealPart-quaternion.fRealPart);
}
inline Double_t TQuaternion::Norm() const {
return sqrt(Norm2());
}
inline Double_t TQuaternion::Norm2() const {
return fRealPart*fRealPart + fVectorPart.Mag2();
}
inline TQuaternion& TQuaternion::Normalize() {
(*this) /= Norm();
return (*this);
}
inline TQuaternion TQuaternion::operator - () const {
return TQuaternion(-fVectorPart,-fRealPart);
}
inline TQuaternion TQuaternion::Conjugate() const {
return TQuaternion(-fVectorPart,fRealPart);
}
#endif