// @(#)root/physics:$Id$
// Author: Eric Anciant 28/06/2005

#ifndef ROOT_TQuaternion
#define ROOT_TQuaternion

#ifndef ROOT_TVector3
#include "TVector3.h"
#endif
#ifndef ROOT_TMath
#include "TMath.h"
#endif


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 *);
   // Constructors from an array : 0 to 2 = vector part, 3 = real part

   TQuaternion(const TQuaternion &);
   // The copy constructor.

   virtual ~TQuaternion();
   // Destructor

   Double_t operator () (int) const;
   inline Double_t operator [] (int) const;
   // Get components by index. 0 to 2 = vector part, 3 = real part

   Double_t & operator () (int);
   inline Double_t & operator [] (int);
   // Set components by index. 0 to 2 = vector part, 3 = real part

   inline TQuaternion& SetRXYZ(Double_t r,Double_t x,Double_t y,Double_t z);
   inline TQuaternion& SetRV(Double_t r, TVector3& vect);
   // Sets components
   TQuaternion& SetAxisQAngle(TVector3& v,Double_t QAngle);
   // Set from vector direction and quaternion angle
   Double_t GetQAngle() const;
   TQuaternion& SetQAngle(Double_t angle);
   // set and get quaternion angle

   inline void GetRXYZ(Double_t *carray) const;
   inline void GetRXYZ(Float_t *carray) const;
   // Get the components into an array : 0 to 2 vector part, 3 real part
   // not checked!

   // ---------------  real to quaternion algebra
   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;

   // ---------------- vector to quaternion algebra
   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;

   // ----------------- quaternion algebra
   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;

   // ------------------ general algebra
   inline Double_t Norm() const; // quaternion magnitude
   inline Double_t Norm2() const; // quaternion squared magnitude
   Double_t QMag() const { return Norm(); } // quaternion magnitude
   Double_t QMag2() const { return Norm2(); } // quaternion squared magnitude
   inline TQuaternion& Normalize();  // normalize quaternion
   inline TQuaternion operator - () const; // Unary minus.
   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;          // Real part
   TVector3 fVectorPart; // vector part

   ClassDef(TQuaternion,1) // a quaternion class
};


// getters / setters

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); }

// ------------------ real to quaternion algebra

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); // keep numericaly compliant with operator/(Double_t)
      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);

// ------------------- vector to quaternion algebra

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);

// --------------- quaternion algebra

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) {
   if (&quat != this) {
      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);
}

// ---------------- general
inline Double_t TQuaternion::Norm() const {
   return TMath::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

 TQuaternion.h:1
 TQuaternion.h:2
 TQuaternion.h:3
 TQuaternion.h:4
 TQuaternion.h:5
 TQuaternion.h:6
 TQuaternion.h:7
 TQuaternion.h:8
 TQuaternion.h:9
 TQuaternion.h:10
 TQuaternion.h:11
 TQuaternion.h:12
 TQuaternion.h:13
 TQuaternion.h:14
 TQuaternion.h:15
 TQuaternion.h:16
 TQuaternion.h:17
 TQuaternion.h:18
 TQuaternion.h:19
 TQuaternion.h:20
 TQuaternion.h:21
 TQuaternion.h:22
 TQuaternion.h:23
 TQuaternion.h:24
 TQuaternion.h:25
 TQuaternion.h:26
 TQuaternion.h:27
 TQuaternion.h:28
 TQuaternion.h:29
 TQuaternion.h:30
 TQuaternion.h:31
 TQuaternion.h:32
 TQuaternion.h:33
 TQuaternion.h:34
 TQuaternion.h:35
 TQuaternion.h:36
 TQuaternion.h:37
 TQuaternion.h:38
 TQuaternion.h:39
 TQuaternion.h:40
 TQuaternion.h:41
 TQuaternion.h:42
 TQuaternion.h:43
 TQuaternion.h:44
 TQuaternion.h:45
 TQuaternion.h:46
 TQuaternion.h:47
 TQuaternion.h:48
 TQuaternion.h:49
 TQuaternion.h:50
 TQuaternion.h:51
 TQuaternion.h:52
 TQuaternion.h:53
 TQuaternion.h:54
 TQuaternion.h:55
 TQuaternion.h:56
 TQuaternion.h:57
 TQuaternion.h:58
 TQuaternion.h:59
 TQuaternion.h:60
 TQuaternion.h:61
 TQuaternion.h:62
 TQuaternion.h:63
 TQuaternion.h:64
 TQuaternion.h:65
 TQuaternion.h:66
 TQuaternion.h:67
 TQuaternion.h:68
 TQuaternion.h:69
 TQuaternion.h:70
 TQuaternion.h:71
 TQuaternion.h:72
 TQuaternion.h:73
 TQuaternion.h:74
 TQuaternion.h:75
 TQuaternion.h:76
 TQuaternion.h:77
 TQuaternion.h:78
 TQuaternion.h:79
 TQuaternion.h:80
 TQuaternion.h:81
 TQuaternion.h:82
 TQuaternion.h:83
 TQuaternion.h:84
 TQuaternion.h:85
 TQuaternion.h:86
 TQuaternion.h:87
 TQuaternion.h:88
 TQuaternion.h:89
 TQuaternion.h:90
 TQuaternion.h:91
 TQuaternion.h:92
 TQuaternion.h:93
 TQuaternion.h:94
 TQuaternion.h:95
 TQuaternion.h:96
 TQuaternion.h:97
 TQuaternion.h:98
 TQuaternion.h:99
 TQuaternion.h:100
 TQuaternion.h:101
 TQuaternion.h:102
 TQuaternion.h:103
 TQuaternion.h:104
 TQuaternion.h:105
 TQuaternion.h:106
 TQuaternion.h:107
 TQuaternion.h:108
 TQuaternion.h:109
 TQuaternion.h:110
 TQuaternion.h:111
 TQuaternion.h:112
 TQuaternion.h:113
 TQuaternion.h:114
 TQuaternion.h:115
 TQuaternion.h:116
 TQuaternion.h:117
 TQuaternion.h:118
 TQuaternion.h:119
 TQuaternion.h:120
 TQuaternion.h:121
 TQuaternion.h:122
 TQuaternion.h:123
 TQuaternion.h:124
 TQuaternion.h:125
 TQuaternion.h:126
 TQuaternion.h:127
 TQuaternion.h:128
 TQuaternion.h:129
 TQuaternion.h:130
 TQuaternion.h:131
 TQuaternion.h:132
 TQuaternion.h:133
 TQuaternion.h:134
 TQuaternion.h:135
 TQuaternion.h:136
 TQuaternion.h:137
 TQuaternion.h:138
 TQuaternion.h:139
 TQuaternion.h:140
 TQuaternion.h:141
 TQuaternion.h:142
 TQuaternion.h:143
 TQuaternion.h:144
 TQuaternion.h:145
 TQuaternion.h:146
 TQuaternion.h:147
 TQuaternion.h:148
 TQuaternion.h:149
 TQuaternion.h:150
 TQuaternion.h:151
 TQuaternion.h:152
 TQuaternion.h:153
 TQuaternion.h:154
 TQuaternion.h:155
 TQuaternion.h:156
 TQuaternion.h:157
 TQuaternion.h:158
 TQuaternion.h:159
 TQuaternion.h:160
 TQuaternion.h:161
 TQuaternion.h:162
 TQuaternion.h:163
 TQuaternion.h:164
 TQuaternion.h:165
 TQuaternion.h:166
 TQuaternion.h:167
 TQuaternion.h:168
 TQuaternion.h:169
 TQuaternion.h:170
 TQuaternion.h:171
 TQuaternion.h:172
 TQuaternion.h:173
 TQuaternion.h:174
 TQuaternion.h:175
 TQuaternion.h:176
 TQuaternion.h:177
 TQuaternion.h:178
 TQuaternion.h:179
 TQuaternion.h:180
 TQuaternion.h:181
 TQuaternion.h:182
 TQuaternion.h:183
 TQuaternion.h:184
 TQuaternion.h:185
 TQuaternion.h:186
 TQuaternion.h:187
 TQuaternion.h:188
 TQuaternion.h:189
 TQuaternion.h:190
 TQuaternion.h:191
 TQuaternion.h:192
 TQuaternion.h:193
 TQuaternion.h:194
 TQuaternion.h:195
 TQuaternion.h:196
 TQuaternion.h:197
 TQuaternion.h:198
 TQuaternion.h:199
 TQuaternion.h:200
 TQuaternion.h:201
 TQuaternion.h:202
 TQuaternion.h:203
 TQuaternion.h:204
 TQuaternion.h:205
 TQuaternion.h:206
 TQuaternion.h:207
 TQuaternion.h:208
 TQuaternion.h:209
 TQuaternion.h:210
 TQuaternion.h:211
 TQuaternion.h:212
 TQuaternion.h:213
 TQuaternion.h:214
 TQuaternion.h:215
 TQuaternion.h:216
 TQuaternion.h:217
 TQuaternion.h:218
 TQuaternion.h:219
 TQuaternion.h:220
 TQuaternion.h:221
 TQuaternion.h:222
 TQuaternion.h:223
 TQuaternion.h:224
 TQuaternion.h:225
 TQuaternion.h:226
 TQuaternion.h:227
 TQuaternion.h:228
 TQuaternion.h:229
 TQuaternion.h:230
 TQuaternion.h:231
 TQuaternion.h:232
 TQuaternion.h:233
 TQuaternion.h:234
 TQuaternion.h:235
 TQuaternion.h:236
 TQuaternion.h:237
 TQuaternion.h:238
 TQuaternion.h:239
 TQuaternion.h:240
 TQuaternion.h:241
 TQuaternion.h:242
 TQuaternion.h:243
 TQuaternion.h:244
 TQuaternion.h:245
 TQuaternion.h:246
 TQuaternion.h:247
 TQuaternion.h:248
 TQuaternion.h:249
 TQuaternion.h:250
 TQuaternion.h:251
 TQuaternion.h:252
 TQuaternion.h:253
 TQuaternion.h:254
 TQuaternion.h:255
 TQuaternion.h:256
 TQuaternion.h:257
 TQuaternion.h:258
 TQuaternion.h:259
 TQuaternion.h:260
 TQuaternion.h:261
 TQuaternion.h:262
 TQuaternion.h:263
 TQuaternion.h:264
 TQuaternion.h:265
 TQuaternion.h:266
 TQuaternion.h:267
 TQuaternion.h:268
 TQuaternion.h:269
 TQuaternion.h:270
 TQuaternion.h:271
 TQuaternion.h:272
 TQuaternion.h:273
 TQuaternion.h:274
 TQuaternion.h:275
 TQuaternion.h:276
 TQuaternion.h:277
 TQuaternion.h:278
 TQuaternion.h:279
 TQuaternion.h:280
 TQuaternion.h:281
 TQuaternion.h:282
 TQuaternion.h:283
 TQuaternion.h:284
 TQuaternion.h:285
 TQuaternion.h:286
 TQuaternion.h:287
 TQuaternion.h:288
 TQuaternion.h:289
 TQuaternion.h:290
 TQuaternion.h:291
 TQuaternion.h:292