library: libPhysics #include "TQuaternion.h"

# TQuaternion

class description - source file - inheritance tree (.pdf)

## class TQuaternion : public TObject

| Inheritance Chart:
`TObject`
| <- | `TQuaternion` |

        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&)
              TQuaternion operator*(Double_t real) const
              TQuaternion operator+(Double_t real) const
              TQuaternion operator-(Double_t real) const
              TQuaternion operator/(Double_t real) const
              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
              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
              TQuaternion operator-() const
              TQuaternion Conjugate() const
              TQuaternion Invert() const
                          ~TQuaternion()
           static TClass* Class()
             TQuaternion& DivideLeft(const TVector3& vector)
             TQuaternion& DivideLeft(const TQuaternion& quaternion)
                 Double_t GetQAngle() const
                     void GetRXYZ(Double_t* carray) const
                     void GetRXYZ(Float_t* carray) const
          virtual TClass* IsA() const
             TQuaternion& MultiplyLeft(const TVector3& vector)
             TQuaternion& MultiplyLeft(const TQuaternion& quaternion)
                 Double_t Norm() const
                 Double_t Norm2() const
             TQuaternion& Normalize()
                   Bool_t operator!=(Double_t r) const
                   Bool_t operator!=(const TVector3& V) const
                   Bool_t operator!=(const TQuaternion& Q) const
                 Double_t operator()(int) const
                Double_t& operator()(int)
             TQuaternion& operator*=(Double_t real)
             TQuaternion& operator*=(const TVector3& vector)
             TQuaternion& operator*=(const TQuaternion& quaternion)
             TQuaternion& operator+=(Double_t real)
             TQuaternion& operator+=(const TVector3& vect)
             TQuaternion& operator+=(const TQuaternion& quaternion)
             TQuaternion& operator-=(Double_t real)
             TQuaternion& operator-=(const TVector3& vect)
             TQuaternion& operator-=(const TQuaternion& quaternion)
             TQuaternion& operator/=(Double_t real)
             TQuaternion& operator/=(const TVector3& vector)
             TQuaternion& operator/=(const TQuaternion& quaternion)
             TQuaternion& operator=(Double_t r)
             TQuaternion& operator=(const TVector3& vect)
             TQuaternion& operator=(const TQuaternion& quat)
                   Bool_t operator==(Double_t r) const
                   Bool_t operator==(const TVector3& V) const
                   Bool_t operator==(const TQuaternion& Q) const
                 Double_t operator[](int i) const
                Double_t& operator[](int i)
             virtual void Print(Option_t* option = "") const
                 Double_t QMag() const
                 Double_t QMag2() const
                     void Rotate(TVector3& vect) const
                 TVector3 Rotation(const TVector3& vect) const
             TQuaternion& SetAxisQAngle(TVector3& v, Double_t QAngle)
             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 ShowMembers(TMemberInspector& insp, char* parent)
             virtual void Streamer(TBuffer& b)
                     void StreamerNVirtual(TBuffer& b)

### Data Members

        public:

          Double_t fRealPart    Real part
          TVector3 fVectorPart  vector part

## Class Description

    ____________________

      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).u
(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.

TQuaternion(const TQuaternion & q) : TObject(q), fRealPart(q.fRealPart), fVectorPart(q.fVectorPart)

TQuaternion(const TVector3 & vect, Double_t real) : fRealPart(real), fVectorPart(vect)

TQuaternion(const Double_t * x0) : fRealPart(x0[3]), fVectorPart(x0)

TQuaternion(const Float_t * x0) : fRealPart(x0[3]), fVectorPart(x0)

TQuaternion(Double_t real, Double_t X, Double_t Y, Double_t Z) : fRealPart(real), fVectorPart(X,Y,Z)

~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& MultiplyLeft(const TVector3 &vect)

     left multitplication

TQuaternion LeftProduct(const TVector3 &vect) const

     left product

TQuaternion& DivideLeft(const TVector3 &vect)

     left division

TQuaternion LeftQuotient(const TVector3 &vect) const

     left quotient

TQuaternion& MultiplyLeft(const TQuaternion &quaternion)

     left multiplication

TQuaternion LeftProduct(const TQuaternion &quaternion) const

     left product

TQuaternion& DivideLeft(const TQuaternion &quaternion)

     left division

TQuaternion LeftQuotient(const TQuaternion& quaternion) const

     left 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*) const

### Inline Functions

                Double_t operator()(int) const
                Double_t operator[](int i) const
               Double_t& operator()(int)
               Double_t& operator[](int i)
            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
            TQuaternion& operator=(Double_t r)
                  Bool_t operator==(Double_t r) const
                  Bool_t operator!=(Double_t r) const
            TQuaternion& operator+=(Double_t real)
            TQuaternion& operator-=(Double_t real)
            TQuaternion& operator*=(Double_t real)
            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
            TQuaternion& operator=(const TVector3& vect)
                  Bool_t operator==(const TVector3& V) const
                  Bool_t operator!=(const TVector3& V) const
            TQuaternion& operator+=(const TVector3& vect)
            TQuaternion& operator-=(const TVector3& vect)
            TQuaternion& operator*=(const TVector3& vector)
            TQuaternion& operator/=(const TVector3& vector)
             TQuaternion operator+(const TVector3& vector) const
             TQuaternion operator-(const TVector3& vector) const
             TQuaternion operator*(const TVector3& vector) const
             TQuaternion operator/(const TVector3& vector) const
            TQuaternion& operator=(const TQuaternion& quat)
                  Bool_t operator==(const TQuaternion& Q) const
                  Bool_t operator!=(const TQuaternion& Q) const
            TQuaternion& operator+=(const TQuaternion& quaternion)
            TQuaternion& operator-=(const TQuaternion& quaternion)
            TQuaternion& operator*=(const TQuaternion& quaternion)
            TQuaternion& operator/=(const TQuaternion& quaternion)
             TQuaternion operator+(const TQuaternion& quaternion) const
             TQuaternion operator-(const TQuaternion& quaternion) const
             TQuaternion operator*(const TQuaternion& quaternion) const
             TQuaternion operator/(const TQuaternion& quaternion) const
                Double_t Norm() const
                Double_t Norm2() const
                Double_t QMag() const
                Double_t QMag2() const
            TQuaternion& Normalize()
             TQuaternion operator-() const
             TQuaternion Conjugate() const
                 TClass* Class()
                 TClass* IsA() const
                    void ShowMembers(TMemberInspector& insp, char* parent)
                    void Streamer(TBuffer& b)
                    void StreamerNVirtual(TBuffer& b)

Author: Eric Anciant 28/06/2005
Last update: root/physics:$Name: $:$Id: TQuaternion.cxx,v 1.1 2005/06/28 07:10:08 brun Exp $