ROOT » MATH » PHYSICS » TQuaternion

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.

More information :

en.wikipedia.org/wiki/Quaternions_and_spatial_rotation .

en.wikipedia.org/wiki/Quaternion .

_______________________________________________

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()
voidTObject::AbstractMethod(const char* method) const
virtual voidTObject::AppendPad(Option_t* option = "")
virtual voidTObject::Browse(TBrowser* b)
static TClass*Class()
virtual const char*TObject::ClassName() const
virtual voidTObject::Clear(Option_t* = "")
virtual TObject*TObject::Clone(const char* newname = "") const
virtual Int_tTObject::Compare(const TObject* obj) const
TQuaternionConjugate() const
virtual voidTObject::Copy(TObject& object) const
virtual voidTObject::Delete(Option_t* option = "")MENU
virtual Int_tTObject::DistancetoPrimitive(Int_t px, Int_t py)
TQuaternion&DivideLeft(const TVector3& vector)
TQuaternion&DivideLeft(const TQuaternion& quaternion)
virtual voidTObject::Draw(Option_t* option = "")
virtual voidTObject::DrawClass() constMENU
virtual TObject*TObject::DrawClone(Option_t* option = "") constMENU
virtual voidTObject::Dump() constMENU
virtual voidTObject::Error(const char* method, const char* msgfmt) const
virtual voidTObject::Execute(const char* method, const char* params, Int_t* error = 0)
virtual voidTObject::Execute(TMethod* method, TObjArray* params, Int_t* error = 0)
virtual voidTObject::ExecuteEvent(Int_t event, Int_t px, Int_t py)
virtual voidTObject::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_tTObject::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_tTObject::GetObjectStat()
virtual Option_t*TObject::GetOption() const
Double_tGetQAngle() const
voidGetRXYZ(Double_t* carray) const
voidGetRXYZ(Float_t* carray) const
virtual const char*TObject::GetTitle() const
virtual UInt_tTObject::GetUniqueID() const
virtual Bool_tTObject::HandleTimer(TTimer* timer)
virtual ULong_tTObject::Hash() const
virtual voidTObject::Info(const char* method, const char* msgfmt) const
virtual Bool_tTObject::InheritsFrom(const char* classname) const
virtual Bool_tTObject::InheritsFrom(const TClass* cl) const
virtual voidTObject::Inspect() constMENU
TQuaternionInvert() const
voidTObject::InvertBit(UInt_t f)
virtual TClass*IsA() const
virtual Bool_tTObject::IsEqual(const TObject* obj) const
virtual Bool_tTObject::IsFolder() const
Bool_tTObject::IsOnHeap() const
virtual Bool_tTObject::IsSortable() const
Bool_tTObject::IsZombie() const
TQuaternionLeftProduct(const TVector3& vector) const
TQuaternionLeftProduct(const TQuaternion& quaternion) const
TQuaternionLeftQuotient(const TVector3& vector) const
TQuaternionLeftQuotient(const TQuaternion& quaternion) const
virtual voidTObject::ls(Option_t* option = "") const
voidTObject::MayNotUse(const char* method) const
TQuaternion&MultiplyLeft(const TVector3& vector)
TQuaternion&MultiplyLeft(const TQuaternion& quaternion)
Double_tNorm() const
Double_tNorm2() const
TQuaternion&Normalize()
virtual Bool_tTObject::Notify()
voidTObject::Obsolete(const char* method, const char* asOfVers, const char* removedFromVers) const
voidTObject::operator delete(void* ptr)
voidTObject::operator delete(void* ptr, void* vp)
voidTObject::operator delete[](void* ptr)
voidTObject::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_toperator!=(Double_t r) const
Bool_toperator!=(const TVector3&) const
Bool_toperator!=(const TQuaternion&) const
Double_toperator()(int) const
Double_t&operator()(int)
TQuaternionoperator*(Double_t real) const
TQuaternionoperator*(const TVector3& vector) const
TQuaternionoperator*(const TQuaternion& quaternion) const
TQuaternion&operator*=(Double_t real)
TQuaternion&operator*=(const TVector3& vector)
TQuaternion&operator*=(const TQuaternion& quaternion)
TQuaternionoperator+(Double_t real) const
TQuaternionoperator+(const TVector3& vector) const
TQuaternionoperator+(const TQuaternion& quaternion) const
TQuaternion&operator+=(Double_t real)
TQuaternion&operator+=(const TVector3& vector)
TQuaternion&operator+=(const TQuaternion& quaternion)
TQuaternionoperator-() const
TQuaternionoperator-(Double_t real) const
TQuaternionoperator-(const TVector3& vector) const
TQuaternionoperator-(const TQuaternion& quaternion) const
TQuaternion&operator-=(Double_t real)
TQuaternion&operator-=(const TVector3& vector)
TQuaternion&operator-=(const TQuaternion& quaternion)
TQuaternionoperator/(Double_t real) const
TQuaternionoperator/(const TVector3& vector) const
TQuaternionoperator/(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_toperator==(Double_t r) const
Bool_toperator==(const TVector3&) const
Bool_toperator==(const TQuaternion&) const
Double_toperator[](int) const
Double_t&operator[](int)
virtual voidTObject::Paint(Option_t* option = "")
virtual voidTObject::Pop()
virtual voidPrint(Option_t* option = "") const
Double_tQMag() const
Double_tQMag2() const
virtual Int_tTObject::Read(const char* name)
virtual voidTObject::RecursiveRemove(TObject* obj)
voidTObject::ResetBit(UInt_t f)
voidRotate(TVector3& vect) const
TVector3Rotation(const TVector3& vect) const
virtual voidTObject::SaveAs(const char* filename = "", Option_t* option = "") constMENU
virtual voidTObject::SavePrimitive(ostream& out, Option_t* option = "")
TQuaternion&SetAxisQAngle(TVector3& v, Double_t QAngle)
voidTObject::SetBit(UInt_t f)
voidTObject::SetBit(UInt_t f, Bool_t set)
virtual voidTObject::SetDrawOption(Option_t* option = "")MENU
static voidTObject::SetDtorOnly(void* obj)
static voidTObject::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 voidTObject::SetUniqueID(UInt_t uid)
virtual voidShowMembers(TMemberInspector& insp) const
virtual voidStreamer(TBuffer&)
voidStreamerNVirtual(TBuffer& ClassDef_StreamerNVirtual_b)
virtual voidTObject::SysError(const char* method, const char* msgfmt) const
Bool_tTObject::TestBit(UInt_t f) const
Int_tTObject::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 voidTObject::UseCurrentStyle()
virtual voidTObject::Warning(const char* method, const char* msgfmt) const
virtual Int_tTObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0)
virtual Int_tTObject::Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0) const
protected:
virtual voidTObject::DoError(int level, const char* location, const char* fmt, va_list va) const
voidTObject::MakeZombie()

Data Members

public:
Double_tfRealPartReal part
TVector3fVectorPartvector part
static TObject::(anonymous)TObject::kBitMask
static TObject::EStatusBitsTObject::kCanDelete
static TObject::EStatusBitsTObject::kCannotPick
static TObject::EStatusBitsTObject::kHasUUID
static TObject::EStatusBitsTObject::kInvalidObject
static TObject::(anonymous)TObject::kIsOnHeap
static TObject::EStatusBitsTObject::kIsReferenced
static TObject::EStatusBitsTObject::kMustCleanup
static TObject::EStatusBitsTObject::kNoContextMenu
static TObject::(anonymous)TObject::kNotDeleted
static TObject::EStatusBitsTObject::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)
{}
~TQuaternion()
{}
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& SetRXYZ(Double_t r, Double_t x, Double_t y, Double_t z)
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=(Double_t r)
TQuaternion& operator+=(Double_t real)
TQuaternion& operator-=(Double_t real)
TQuaternion& operator*=(Double_t real)
TQuaternion& operator/=(Double_t real)
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& Normalize()
TQuaternion Conjugate() const
TQuaternion operator-(Double_t real) const
Double_t QMag() const
{ return Norm(); }
Double_t QMag2() const
{ return Norm2(); }