# class TQuaternion: public TObject

```

A Quaternion Class

```

Quaternion is a 4-component mathematic object quite convenient when dealing with space rotation (or reference frame transformation).

In short, think of quaternion Q as a 3-vector augmented by a real number. Q = Q|r + Q|V

Quaternion multiplication :

Quaternion multiplication is given by :
Q.Q' = (Q|r + Q|V )*( Q'|r + Q'|V)
= [ Q|r*Q'|r - Q|V*Q'|V ] + [ Q|r*Q'|V + Q'|r*Q|V + Q|V X Q'|V ]

where :
Q|r*Q'|r is a real number product of real numbers
Q|V*Q'|V is a real number, scalar product of two 3-vectors
Q|r*Q'|V is a 3-vector, scaling of a 3-vector by a real number
Q|VXQ'|V is a 3-vector, cross product of two 3-vectors

Thus, quaternion product is a generalization of real number product and product of a vector by a real number. Product of two pure vectors gives a quaternion whose real part is the opposite of scalar product and the vector part the cross product.

The conjugate of a quaternion Q = Q|r + Q|V is Q_bar = Q|r - Q|V

The magnitude of a quaternion Q is given by |Q|² = Q.Q_bar = Q_bar.Q = Q²|r + |Q|V

Therefore, the inverse of a quaternion is Q-1 = Q_bar /|Q|²

"unit" quaternion is a quaternion of magnitude 1 : |Q|² = 1.
Unit quaternions are a subset of the quaternions set.

Quaternion and rotations :

A rotation of angle f around a given axis, is represented by a unit quaternion Q :
- The axis of the rotation is given by the vector part of Q.
- The ratio between the magnitude of the vector part and the real part of Q equals tan(f/2).

In other words : Q = Q|r + Q|V = cos(f/2) + sin(f/2).
(where u is a unit vector // to the rotation axis, cos(f/2) is the real part, sin(f/2).u is the vector part)
Note : The quaternion of identity is QI = cos(0) + sin(0)*(any vector) = 1.

The composition of two rotations is described by the product of the two corresponding quaternions.
As for 3-space rotations, quaternion multiplication is not commutative !

Q = Q1.Q2 represents the composition of the successive rotation R1 and R2 expressed in the current frame (the axis of rotation hold by Q2 is expressed in the frame as it is after R1 rotation).
Q = Q2.Q1 represents the composition of the successive rotation R1 and R2 expressed in the initial reference frame.

The inverse of a rotation is a rotation about the same axis but of opposite angle, thus if Q is a unit quaternion,
Q = cos(f/2) + sin(f/2).u = Q|r + Q|V, then :
Q-1 =cos(-f/2) + sin(-f/2).u = cos(f/2) - sin(f/2).u = Q|r -Q|V is its inverse quaternion.

One verifies that :
Q.Q-1 = Q-1.Q = Q|r*Q|r + Q|V*Q|V + Q|r*Q|V -Q|r*Q|V + Q|VXQ|V
= Q²|r + Q²|V = 1

The rotation of a vector V by the rotation described by a unit quaternion Q is obtained by the following operation : V' = Q*V*Q-1, considering V as a quaternion whose real part is null.

Numeric computation considerations :

Numerically, the quaternion multiplication involves 12 additions and 16 multiplications.
It is therefore faster than 3x3 matrixes multiplication involving 18 additions and 27 multiplications.

On the contrary, rotation of a vector by the above formula ( Q*V*Q-1 ) involves 18 additions and 24 multiplications, whereas multiplication of a 3-vector by a 3x3 matrix involves only 6 additions and 9 multiplications.

When dealing with numerous composition of space rotation, it is therefore faster to use quaternion product. On the other hand if a huge set of vectors must be rotated by a given quaternion, it is more optimized to convert the quaternion into a rotation matrix once, and then use that later to rotate the set of vectors.

_______________________________________________

This Class represents all quaternions (unit or non-unit)
It possesses a Normalize() method to make a given quaternion unit
The Rotate(TVector3&) and Rotation(TVector3&) methods can be used even for a non-unit quaternion, in that case, the proper normalization is applied to perform the rotation.

A TRotation constructor exists than takes a quaternion for parameter (even non-unit), in that cas the proper normalisation is applied.

## Function Members (Methods)

public:
 virtual ~TQuaternion() void TObject::AbstractMethod(const char* method) const virtual void TObject::AppendPad(Option_t* option = "") virtual void TObject::Browse(TBrowser* b) static TClass* Class() virtual const char* TObject::ClassName() const virtual void TObject::Clear(Option_t* = "") virtual TObject* TObject::Clone(const char* newname = "") const virtual Int_t TObject::Compare(const TObject* obj) const TQuaternion Conjugate() const virtual void TObject::Copy(TObject& object) const virtual void TObject::Delete(Option_t* option = "")MENU virtual Int_t TObject::DistancetoPrimitive(Int_t px, Int_t py) TQuaternion& DivideLeft(const TVector3& vector) TQuaternion& DivideLeft(const TQuaternion& quaternion) virtual void TObject::Draw(Option_t* option = "") virtual void TObject::DrawClass() constMENU virtual TObject* TObject::DrawClone(Option_t* option = "") constMENU virtual void TObject::Dump() constMENU virtual void TObject::Error(const char* method, const char* msgfmt) const virtual void TObject::Execute(const char* method, const char* params, Int_t* error = 0) virtual void TObject::Execute(TMethod* method, TObjArray* params, Int_t* error = 0) virtual void TObject::ExecuteEvent(Int_t event, Int_t px, Int_t py) virtual void TObject::Fatal(const char* method, const char* msgfmt) const virtual TObject* TObject::FindObject(const char* name) const virtual TObject* TObject::FindObject(const TObject* obj) const virtual Option_t* TObject::GetDrawOption() const static Long_t TObject::GetDtorOnly() virtual const char* TObject::GetIconName() const virtual const char* TObject::GetName() const virtual char* TObject::GetObjectInfo(Int_t px, Int_t py) const static Bool_t TObject::GetObjectStat() virtual Option_t* TObject::GetOption() const Double_t GetQAngle() const void GetRXYZ(Double_t* carray) const void GetRXYZ(Float_t* carray) const virtual const char* TObject::GetTitle() const virtual UInt_t TObject::GetUniqueID() const virtual Bool_t TObject::HandleTimer(TTimer* timer) virtual ULong_t TObject::Hash() const virtual void TObject::Info(const char* method, const char* msgfmt) const virtual Bool_t TObject::InheritsFrom(const char* classname) const virtual Bool_t TObject::InheritsFrom(const TClass* cl) const virtual void TObject::Inspect() constMENU TQuaternion Invert() const void TObject::InvertBit(UInt_t f) virtual TClass* IsA() const virtual Bool_t TObject::IsEqual(const TObject* obj) const virtual Bool_t TObject::IsFolder() const Bool_t TObject::IsOnHeap() const virtual Bool_t TObject::IsSortable() const Bool_t TObject::IsZombie() const TQuaternion LeftProduct(const TVector3& vector) const TQuaternion LeftProduct(const TQuaternion& quaternion) const TQuaternion LeftQuotient(const TVector3& vector) const TQuaternion LeftQuotient(const TQuaternion& quaternion) const virtual void TObject::ls(Option_t* option = "") const void TObject::MayNotUse(const char* method) const TQuaternion& MultiplyLeft(const TVector3& vector) TQuaternion& MultiplyLeft(const TQuaternion& quaternion) Double_t Norm() const Double_t Norm2() const TQuaternion& Normalize() virtual Bool_t TObject::Notify() void TObject::Obsolete(const char* method, const char* asOfVers, const char* removedFromVers) const void TObject::operator delete(void* ptr) void TObject::operator delete(void* ptr, void* vp) void TObject::operator delete[](void* ptr) void TObject::operator delete[](void* ptr, void* vp) void* TObject::operator new(size_t sz) void* TObject::operator new(size_t sz, void* vp) void* TObject::operator new[](size_t sz) void* TObject::operator new[](size_t sz, void* vp) Bool_t operator!=(Double_t r) const Bool_t operator!=(const TVector3&) const Bool_t operator!=(const TQuaternion&) const Double_t operator()(int) const Double_t& operator()(int) TQuaternion operator*(Double_t real) const TQuaternion operator*(const TVector3& vector) const TQuaternion operator*(const TQuaternion& quaternion) const TQuaternion& operator*=(Double_t real) TQuaternion& operator*=(const TVector3& vector) TQuaternion& operator*=(const TQuaternion& quaternion) TQuaternion operator+(Double_t real) const TQuaternion operator+(const TVector3& vector) const TQuaternion operator+(const TQuaternion& quaternion) const TQuaternion& operator+=(Double_t real) TQuaternion& operator+=(const TVector3& vector) TQuaternion& operator+=(const TQuaternion& quaternion) TQuaternion operator-() const TQuaternion operator-(Double_t real) const TQuaternion operator-(const TVector3& vector) const TQuaternion operator-(const TQuaternion& quaternion) const TQuaternion& operator-=(Double_t real) TQuaternion& operator-=(const TVector3& vector) TQuaternion& operator-=(const TQuaternion& quaternion) TQuaternion operator/(Double_t real) const TQuaternion operator/(const TVector3& vector) const TQuaternion operator/(const TQuaternion& quaternion) const TQuaternion& operator/=(Double_t real) TQuaternion& operator/=(const TVector3& vector) TQuaternion& operator/=(const TQuaternion& quaternion) TQuaternion& operator=(Double_t r) TQuaternion& operator=(const TVector3&) TQuaternion& operator=(const TQuaternion&) Bool_t operator==(Double_t r) const Bool_t operator==(const TVector3&) const Bool_t operator==(const TQuaternion&) const Double_t operator[](int) const Double_t& operator[](int) virtual void TObject::Paint(Option_t* option = "") virtual void TObject::Pop() virtual void Print(Option_t* option = "") const Double_t QMag() const Double_t QMag2() const virtual Int_t TObject::Read(const char* name) virtual void TObject::RecursiveRemove(TObject* obj) void TObject::ResetBit(UInt_t f) void Rotate(TVector3& vect) const TVector3 Rotation(const TVector3& vect) const virtual void TObject::SaveAs(const char* filename = "", Option_t* option = "") constMENU virtual void TObject::SavePrimitive(ostream& out, Option_t* option = "") TQuaternion& SetAxisQAngle(TVector3& v, Double_t QAngle) void TObject::SetBit(UInt_t f) void TObject::SetBit(UInt_t f, Bool_t set) virtual void TObject::SetDrawOption(Option_t* option = "")MENU static void TObject::SetDtorOnly(void* obj) static void TObject::SetObjectStat(Bool_t stat) TQuaternion& SetQAngle(Double_t angle) TQuaternion& SetRV(Double_t r, TVector3& vect) TQuaternion& SetRXYZ(Double_t r, Double_t x, Double_t y, Double_t z) virtual void TObject::SetUniqueID(UInt_t uid) virtual void ShowMembers(TMemberInspector& insp) const virtual void Streamer(TBuffer&) void StreamerNVirtual(TBuffer& ClassDef_StreamerNVirtual_b) virtual void TObject::SysError(const char* method, const char* msgfmt) const Bool_t TObject::TestBit(UInt_t f) const Int_t TObject::TestBits(UInt_t f) const TQuaternion(const Double_t*) TQuaternion(const Float_t*) TQuaternion(const TQuaternion&) TQuaternion(const TVector3& vector, Double_t real = 0) TQuaternion(Double_t real = 0, Double_t X = 0, Double_t Y = 0, Double_t Z = 0) virtual void TObject::UseCurrentStyle() virtual void TObject::Warning(const char* method, const char* msgfmt) const virtual Int_t TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) virtual Int_t TObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) const
protected:
 virtual void TObject::DoError(int level, const char* location, const char* fmt, va_list va) const void TObject::MakeZombie()

## Data Members

public:
 Double_t fRealPart Real part TVector3 fVectorPart vector part static TObject::(anonymous) TObject::kBitMask static TObject::EStatusBits TObject::kCanDelete static TObject::EStatusBits TObject::kCannotPick static TObject::EStatusBits TObject::kHasUUID static TObject::EStatusBits TObject::kInvalidObject static TObject::(anonymous) TObject::kIsOnHeap static TObject::EStatusBits TObject::kIsReferenced static TObject::EStatusBits TObject::kMustCleanup static TObject::EStatusBits TObject::kNoContextMenu static TObject::(anonymous) TObject::kNotDeleted static TObject::EStatusBits TObject::kObjInCanvas static TObject::(anonymous) TObject::kOverwrite static TObject::(anonymous) TObject::kSingleKey static TObject::(anonymous) TObject::kWriteDelete static TObject::(anonymous) TObject::kZombie

## Class Charts

Inheritance Chart:
 TObject
TQuaternion

## Function documentation

TQuaternion(const TQuaternion& )
`{}`
TQuaternion(const TVector3& vector, Double_t real = 0)
`{}`
TQuaternion(const Double_t* )
`{}`
TQuaternion(const Float_t* )
`{}`
TQuaternion(Double_t real = 0, Double_t X = 0, Double_t Y = 0, Double_t Z = 0)
`{}`

`{}`
Double_t GetQAngle() const
``` Get angle of quaternion (rad)
N.B : this angle is half of the corresponding rotation angle
```
TQuaternion& SetQAngle(Double_t angle)
``` Set angle of quaternion (rad) - keep quaternion norm
N.B : this angle is half of the corresponding rotation angle
```
TQuaternion& SetAxisQAngle(TVector3& v, Double_t QAngle)
``` set quaternion from vector and angle (rad)
quaternion is set as unitary
N.B : this angle is half of the corresponding rotation angle
```
TQuaternion operator+(Double_t real) const
``` sum of quaternion with a real
```
TQuaternion operator-(Double_t real) const
``` substraction of real to quaternion
```
TQuaternion operator*(Double_t real) const
``` product of quaternion with a real
```
TQuaternion operator/(Double_t real) const
``` division by a real
```
TQuaternion operator+(const TVector3& vector) const
``` sum of quaternion with a real
```
TQuaternion operator-(const TVector3& vector) const
``` substraction of real to quaternion
```
TQuaternion& MultiplyLeft(const TVector3& vector)
``` left multitplication
```
TQuaternion& operator*=(const TVector3& vector)
``` right multiplication
```
TQuaternion LeftProduct(const TVector3& vector) const
``` left product
```
TQuaternion operator*(const TVector3& vector) const
``` right product
```
TQuaternion& DivideLeft(const TVector3& vector)
``` left division
```
TQuaternion& operator/=(const TVector3& vector)
``` right division
```
TQuaternion LeftQuotient(const TVector3& vector) const
``` left quotient
```
TQuaternion operator/(const TVector3& vector) const
```  right quotient
```
TQuaternion& operator*=(const TQuaternion& quaternion)
``` right multiplication
```
TQuaternion& MultiplyLeft(const TQuaternion& quaternion)
``` left multiplication
```
TQuaternion LeftProduct(const TQuaternion& quaternion) const
``` left product
```
TQuaternion operator*(const TQuaternion& quaternion) const
``` right product
```
TQuaternion& DivideLeft(const TQuaternion& quaternion)
``` left division
```
TQuaternion& operator/=(const TQuaternion& quaternion)
``` right division
```
TQuaternion LeftQuotient(const TQuaternion& quaternion) const
``` left quotient
```
TQuaternion operator/(const TQuaternion& quaternion) const
``` right quotient
```
TQuaternion Invert() const
``` invert
```
void Rotate(TVector3& vect) const
``` rotate vect by current quaternion
```
TVector3 Rotation(const TVector3& vect) const
``` rotation of vect by current quaternion
```
void Print(Option_t* option = "") const
```Print Quaternion parameters
```

TQuaternion& SetRV(Double_t r, TVector3& vect)
void GetRXYZ(Double_t* carray) const
void GetRXYZ(Float_t* carray) const
Double_t & operator[](int )
`{ return operator()(i); }`
Double_t operator[](int ) const
`{ return operator()(i); }`

TQuaternion& operator=(const TVector3& )
TQuaternion& operator+=(const TVector3& vector)
TQuaternion& operator-=(const TVector3& vector)
TQuaternion& operator=(const TQuaternion& )
TQuaternion& operator+=(const TQuaternion& quaternion)
TQuaternion& operator-=(const TQuaternion& quaternion)
TQuaternion operator+(const TQuaternion& quaternion) const
TQuaternion operator-(const TQuaternion& quaternion) const
Double_t Norm() const
``` ---------------- general
```
Double_t Norm2() const
TQuaternion Conjugate() const
TQuaternion operator-(Double_t real) const
Double_t QMag() const
`{ return Norm(); }`
Double_t QMag2() const
`{ return Norm2(); }`