96 ClassImp(TQuaternion);
101 TQuaternion::TQuaternion(
const TQuaternion & q) : TObject(q),
102 fRealPart(q.fRealPart), fVectorPart(q.fVectorPart) {}
104 TQuaternion::TQuaternion(
const TVector3 & vect, Double_t real)
105 : fRealPart(real), fVectorPart(vect) {}
107 TQuaternion::TQuaternion(
const Double_t * x0)
108 : fRealPart(x0[3]), fVectorPart(x0) {}
110 TQuaternion::TQuaternion(
const Float_t * x0)
111 : fRealPart(x0[3]), fVectorPart(x0) {}
113 TQuaternion::TQuaternion(Double_t real, Double_t X, Double_t Y, Double_t Z)
114 : fRealPart(real), fVectorPart(X,Y,Z) {}
116 TQuaternion::~TQuaternion() {}
121 Double_t TQuaternion::operator () (
int i)
const {
126 return fVectorPart(i);
130 Error(
"operator()(i)",
"bad index (%d) returning 0",i);
138 Double_t & TQuaternion::operator () (
int i) {
143 return fVectorPart(i);
147 Error(
"operator()(i)",
"bad index (%d) returning &fRealPart",i);
155 Double_t TQuaternion::GetQAngle()
const {
156 if (fRealPart == 0)
return TMath::PiOver2();
157 Double_t denominator = fVectorPart.Mag();
158 return atan(denominator/fRealPart);
165 TQuaternion& TQuaternion::SetQAngle(Double_t angle) {
166 Double_t norm = Norm();
167 Double_t normSinV = fVectorPart.Mag();
168 if (normSinV != 0) fVectorPart *= (sin(angle)*norm/normSinV);
169 fRealPart = cos(angle)*norm;
179 TQuaternion& TQuaternion::SetAxisQAngle(TVector3& v,Double_t QAngle) {
181 double norm = v.Mag();
182 if (norm>0) fVectorPart*=(1./norm);
183 fVectorPart*=sin(QAngle);
184 fRealPart = cos(QAngle);
194 TQuaternion TQuaternion::operator+(Double_t real)
const {
195 return TQuaternion(fVectorPart, fRealPart + real);
201 TQuaternion TQuaternion::operator-(Double_t real)
const {
202 return TQuaternion(fVectorPart, fRealPart - real);
208 TQuaternion TQuaternion::operator*(Double_t real)
const {
209 return TQuaternion(fRealPart*real,fVectorPart.x()*real,fVectorPart.y()*real,fVectorPart.z()*real);
216 TQuaternion TQuaternion::operator/(Double_t real)
const {
218 return TQuaternion(fRealPart/real,fVectorPart.x()/real,fVectorPart.y()/real,fVectorPart.z()/real);
220 Error(
"operator/(Double_t)",
"bad value (%f) ignored",real);
226 TQuaternion operator + (Double_t r,
const TQuaternion & q) {
return (q+r); }
227 TQuaternion operator - (Double_t r,
const TQuaternion & q) {
return (-q+r); }
228 TQuaternion operator * (Double_t r,
const TQuaternion & q) {
return (q*r); }
229 TQuaternion operator / (Double_t r,
const TQuaternion & q) {
return (q.Invert()*r); }
236 TQuaternion TQuaternion::operator+(
const TVector3 &vect)
const {
237 return TQuaternion(fVectorPart + vect, fRealPart);
243 TQuaternion TQuaternion::operator-(
const TVector3 &vect)
const {
244 return TQuaternion(fVectorPart - vect, fRealPart);
250 TQuaternion& TQuaternion::MultiplyLeft(
const TVector3 &vect) {
251 Double_t savedRealPart = fRealPart;
252 fRealPart = - (fVectorPart * vect);
253 fVectorPart = vect.Cross(fVectorPart);
254 fVectorPart += (vect * savedRealPart);
262 TQuaternion& TQuaternion::operator*=(
const TVector3 &vect) {
263 Double_t savedRealPart = fRealPart;
264 fRealPart = -(fVectorPart * vect);
265 fVectorPart = fVectorPart.Cross(vect);
266 fVectorPart += (vect * savedRealPart );
274 TQuaternion TQuaternion::LeftProduct(
const TVector3 &vect)
const {
275 return TQuaternion(vect * fRealPart + vect.Cross(fVectorPart), -(fVectorPart * vect));
281 TQuaternion TQuaternion::operator*(
const TVector3 &vect)
const {
282 return TQuaternion(vect * fRealPart + fVectorPart.Cross(vect), -(fVectorPart * vect));
288 TQuaternion& TQuaternion::DivideLeft(
const TVector3 &vect) {
289 Double_t norm2 = vect.Mag2();
293 (*this) *= -(1./norm2);
295 Error(
"DivideLeft(const TVector3)",
"bad norm2 (%f) ignored",norm2);
303 TQuaternion& TQuaternion::operator/=(
const TVector3 &vect) {
304 Double_t norm2 = vect.Mag2();
308 (*this) *= - (1./norm2);
310 Error(
"operator/=(const TVector3 &)",
"bad norm2 (%f) ignored",norm2);
318 TQuaternion TQuaternion::LeftQuotient(
const TVector3 &vect)
const {
319 Double_t norm2 = vect.Mag2();
322 double invNorm2 = 1./norm2;
323 return TQuaternion((vect * -fRealPart - vect.Cross(fVectorPart))*invNorm2,
324 (fVectorPart * vect ) * invNorm2 );
326 Error(
"LeftQuotient(const TVector3 &)",
"bad norm2 (%f) ignored",norm2);
334 TQuaternion TQuaternion::operator/(
const TVector3 &vect)
const {
335 Double_t norm2 = vect.Mag2();
338 double invNorm2 = 1./norm2;
339 return TQuaternion((vect * -fRealPart - fVectorPart.Cross(vect)) * invNorm2,
340 (fVectorPart * vect) * invNorm2 );
342 Error(
"operator/(const TVector3 &)",
"bad norm2 (%f) ignored",norm2);
347 TQuaternion operator + (
const TVector3 &V,
const TQuaternion &Q) {
return (Q+V); }
348 TQuaternion operator - (
const TVector3 &V,
const TQuaternion &Q) {
return (-Q+V); }
349 TQuaternion operator * (
const TVector3 &V,
const TQuaternion &Q) {
return Q.LeftProduct(V); }
351 TQuaternion operator / (
const TVector3 &vect,
const TQuaternion &quat) {
353 TQuaternion res(vect);
363 TQuaternion& TQuaternion::operator*=(
const TQuaternion &quaternion) {
364 Double_t saveRP = fRealPart;
365 TVector3 cross(fVectorPart.Cross(quaternion.fVectorPart));
367 fRealPart = fRealPart * quaternion.fRealPart - fVectorPart * quaternion.fVectorPart;
369 fVectorPart *= quaternion.fRealPart;
370 fVectorPart += quaternion.fVectorPart * saveRP;
371 fVectorPart += cross;
378 TQuaternion& TQuaternion::MultiplyLeft(
const TQuaternion &quaternion) {
379 Double_t saveRP = fRealPart;
380 TVector3 cross(quaternion.fVectorPart.Cross(fVectorPart));
382 fRealPart = fRealPart * quaternion.fRealPart - fVectorPart * quaternion.fVectorPart;
384 fVectorPart *= quaternion.fRealPart;
385 fVectorPart += quaternion.fVectorPart * saveRP;
386 fVectorPart += cross;
394 TQuaternion TQuaternion::LeftProduct(
const TQuaternion &quaternion)
const {
395 return TQuaternion( fVectorPart*quaternion.fRealPart + quaternion.fVectorPart*fRealPart
396 + quaternion.fVectorPart.Cross(fVectorPart),
397 fRealPart*quaternion.fRealPart - fVectorPart*quaternion.fVectorPart );
403 TQuaternion TQuaternion::operator*(
const TQuaternion &quaternion)
const {
404 return TQuaternion(fVectorPart*quaternion.fRealPart + quaternion.fVectorPart*fRealPart
405 + fVectorPart.Cross(quaternion.fVectorPart),
406 fRealPart*quaternion.fRealPart - fVectorPart*quaternion.fVectorPart );
412 TQuaternion& TQuaternion::DivideLeft(
const TQuaternion &quaternion) {
413 Double_t norm2 = quaternion.Norm2();
416 MultiplyLeft(quaternion.Conjugate());
417 (*this) *= (1./norm2);
419 Error(
"DivideLeft(const TQuaternion &)",
"bad norm2 (%f) ignored",norm2);
427 TQuaternion& TQuaternion::operator/=(
const TQuaternion& quaternion) {
428 Double_t norm2 = quaternion.Norm2();
431 (*this) *= quaternion.Conjugate();
433 (*this) *= (1./norm2);
435 Error(
"operator/=(const TQuaternion&)",
"bad norm2 (%f) ignored",norm2);
443 TQuaternion TQuaternion::LeftQuotient(
const TQuaternion& quaternion)
const {
444 Double_t norm2 = quaternion.Norm2();
447 double invNorm2 = 1./norm2;
449 (fVectorPart*quaternion.fRealPart - quaternion.fVectorPart*fRealPart
450 - quaternion.fVectorPart.Cross(fVectorPart)) * invNorm2,
451 (fRealPart*quaternion.fRealPart + fVectorPart*quaternion.fVectorPart)*invNorm2 );
453 Error(
"LeftQuotient(const TQuaternion&)",
"bad norm2 (%f) ignored",norm2);
461 TQuaternion TQuaternion::operator/(
const TQuaternion &quaternion)
const {
462 Double_t norm2 = quaternion.Norm2();
465 double invNorm2 = 1./norm2;
467 (fVectorPart*quaternion.fRealPart - quaternion.fVectorPart*fRealPart
468 - fVectorPart.Cross(quaternion.fVectorPart)) * invNorm2,
469 (fRealPart*quaternion.fRealPart + fVectorPart*quaternion.fVectorPart) * invNorm2 );
471 Error(
"operator/(const TQuaternion &)",
"bad norm2 (%f) ignored",norm2);
479 TQuaternion TQuaternion::Invert()
const {
480 double norm2 = Norm2();
482 double invNorm2 = 1./norm2;
483 return TQuaternion(fVectorPart*(-invNorm2), fRealPart*invNorm2 );
485 Error(
"Invert()",
"bad norm2 (%f) ignored",norm2);
493 void TQuaternion::Rotate(TVector3 & vect)
const {
494 vect = Rotation(vect);
500 TVector3 TQuaternion::Rotation(
const TVector3 & vect)
const {
502 double norm2 = Norm2();
505 TQuaternion quat(*
this);
512 TVector3 cross(fVectorPart.Cross(quat.fVectorPart));
513 quat.fVectorPart *= fRealPart;
514 quat.fVectorPart -= fVectorPart * quat.fRealPart;
515 quat.fVectorPart += cross;
517 return quat.fVectorPart*(1./norm2);
519 Error(
"Rotation()",
"bad norm2 (%f) ignored",norm2);
527 void TQuaternion::Print(Option_t*)
const
529 Printf(
"%s %s (r,x,y,z)=(%f,%f,%f,%f) \n (alpha,rho,theta,phi)=(%f,%f,%f,%f)",GetName(),GetTitle(),
530 fRealPart,fVectorPart.X(),fVectorPart.Y(),fVectorPart.Z(),
531 GetQAngle()*TMath::RadToDeg(),fVectorPart.Mag(),fVectorPart.Theta()*TMath::RadToDeg(),fVectorPart.Phi()*TMath::RadToDeg());