Logo ROOT   6.08/07
Reference Guide
TRotation.cxx
Go to the documentation of this file.
1 // @(#)root/physics:$Id$
2 // Author: Peter Malzacher 19/06/99
3 
4 /** \class TRotation
5  \ingroup Physics
6 
7 The TRotation class describes a rotation of objects of the TVector3 class.
8 It is a 3*3 matrix of Double_t:
9 
10 ~~~
11 | xx xy xz |
12 | yx yy yz |
13 | zx zy zz |
14 ~~~
15 
16 It describes a so called active rotation, i.e. rotation of objects inside
17 a static system of coordinates. In case you want to rotate the frame and
18 want to know the coordinates of objects in the rotated system, you should
19 apply the inverse rotation to the objects. If you want to transform coordinates
20 from the rotated frame to the original frame you have to apply the direct
21 transformation.
22 
23 A rotation around a specified axis means counterclockwise rotation around
24 the positive direction of the axis.
25 
26 
27 ### Declaration, Access, Comparisons
28 
29 ~~~
30  TRotation r; // r initialized as identity
31  TRotation m(r); // m = r
32 ~~~
33 
34 There is no direct way to set the matrix elements - to ensure that
35 a TRotation object always describes a real rotation. But you can get the
36 values by the member functions XX()..ZZ() or the (,)
37 operator:
38 
39 ~~~
40  Double_t xx = r.XX(); // the same as xx=r(0,0)
41  xx = r(0,0);
42 
43  if (r==m) {...} // test for equality
44  if (r!=m) {..} // test for inequality
45  if (r.IsIdentity()) {...} // test for identity
46 ~~~
47 
48 ### Rotation around axes
49 The following matrices describe counterclockwise rotations around coordinate
50 axes
51 
52 ~~~
53  | 1 0 0 |
54 Rx(a) = | 0 cos(a) -sin(a) |
55  | 0 sin(a) cos(a) |
56 
57  | cos(a) 0 sin(a) |
58 Ry(a) = | 0 1 0 |
59  | -sin(a) 0 cos(a) |
60 
61  | cos(a) -sin(a) 0 |
62 Rz(a) = | sin(a) cos(a) 0 |
63  | 0 0 1 |
64 ~~~
65 
66 and are implemented as member functions RotateX(), RotateY() and RotateZ():
67 
68 ~~~
69  r.RotateX(TMath::Pi()); // rotation around the x-axis
70 ~~~
71 
72 ### Rotation around arbitrary axis
73 The member function Rotate() allows to rotate around an arbitrary vector
74 (not necessary a unit one) and returns the result.
75 
76 ~~~
77  r.Rotate(TMath::Pi()/3,TVector3(3,4,5));
78 ~~~
79 
80 It is possible to find a unit vector and an angle, which describe the
81 same rotation as the current one:
82 
83 ~~~
84  Double_t angle;
85  TVector3 axis;
86  r.GetAngleAxis(angle,axis);
87 ~~~
88 
89 ### Rotation of local axes
90 Member function RotateAxes() adds a rotation of local axes to
91 the current rotation and returns the result:
92 
93 ~~~
94  TVector3 newX(0,1,0);
95  TVector3 newY(0,0,1);
96  TVector3 newZ(1,0,0);
97  a.RotateAxes(newX,newY,newZ);
98 ~~~
99 
100 Member functions ThetaX(), ThetaY(), ThetaZ(),
101 PhiX(), PhiY(),PhiZ() return azimuth and polar
102 angles of the rotated axes:
103 
104 ~~~
105  Double_t tx,ty,tz,px,py,pz;
106  tx= a.ThetaX();
107  ...
108  pz= a.PhiZ();
109 ~~~
110 
111 ### Setting The Rotations
112 The member function SetToIdentity() will set the rotation object
113 to the identity (no rotation).
114 
115 With a minor caveat, the Euler angles of the rotation may be set using
116 SetXEulerAngles() or individually set with SetXPhi(),
117 SetXTheta(), and SetXPsi(). These routines set the Euler
118 angles using the X-convention which is defined by a rotation about the Z-axis,
119 about the new X-axis, and about the new Z-axis. This is the convention used
120 in Landau and Lifshitz, Goldstein and other common physics texts. The
121 Y-convention Euler angles can be set with SetYEulerAngles(),
122 SetYPhi(), SetYTheta(), and SetYPsi(). The caveat
123 is that Euler angles usually define the rotation of the new coordinate system
124 with respect to the original system, however, the TRotation class specifies
125 the rotation of the object in the original system (an active rotation). To
126 recover the usual Euler rotations (ie. rotate the system not the object), you
127 must take the inverse of the rotation.
128 
129 The member functions SetXAxis(), SetYAxis(), and
130 SetZAxis() will create a rotation which rotates the requested axis
131 of the object to be parallel to a vector. If used with one argument, the
132 rotation about that axis is arbitrary. If used with two arguments, the
133 second variable defines the XY, YZ, or ZX
134 respectively.
135 
136 
137 ### Inverse rotation
138 
139 ~~~
140  TRotation a,b;
141  ...
142  b = a.Inverse(); // b is inverse of a, a is unchanged
143  b = a.Invert(); // invert a and set b = a
144 ~~~
145 
146 ### Compound Rotations
147 The operator * has been implemented in a way that follows the
148 mathematical notation of a product of the two matrices which describe the
149 two consecutive rotations. Therefore the second rotation should be placed
150 first:
151 
152 ~~~
153  r = r2 * r1;
154 ~~~
155 
156 ### Rotation of TVector3
157 The TRotation class provides an operator * which allows to express
158 a rotation of a TVector3 analog to the mathematical notation
159 
160 ~~~
161  | x' | | xx xy xz | | x |
162  | y' | = | yx yy yz | | y |
163  | z' | | zx zy zz | | z |
164 ~~~
165 
166 e.g.:
167 
168 ~~~
169  TVector3 v(1,1,1);
170  v = r * v;
171 ~~~
172 
173 You can also use the Transform() member function or the operator *= of the
174 TVector3 class:
175 
176 ~~~
177  TVector3 v;
178  TRotation r;
179  v.Transform(r);
180  v *= r; //Attention v = r * v
181 ~~~
182 */
183 
184 #include "TRotation.h"
185 #include "TMath.h"
186 #include "TQuaternion.h"
187 #include "TError.h"
188 
190 
191 #define TOLERANCE (1.0E-6)
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// Constructor.
195 
197 : fxx(1.0), fxy(0.0), fxz(0.0), fyx(0.0), fyy(1.0), fyz(0.0),
198  fzx(0.0), fzy(0.0), fzz(1.0) {}
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// Constructor.
202 
204  fxx(m.fxx), fxy(m.fxy), fxz(m.fxz), fyx(m.fyx), fyy(m.fyy), fyz(m.fyz),
205  fzx(m.fzx), fzy(m.fzy), fzz(m.fzz) {}
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 /// Constructor.
209 
211  Double_t myx, Double_t myy, Double_t myz,
212  Double_t mzx, Double_t mzy, Double_t mzz)
213 : fxx(mxx), fxy(mxy), fxz(mxz), fyx(myx), fyy(myy), fyz(myz),
214  fzx(mzx), fzy(mzy), fzz(mzz) {}
215 
216 ////////////////////////////////////////////////////////////////////////////////
217 /// Dereferencing operator const.
218 
219 Double_t TRotation::operator() (int i, int j) const {
220  if (i == 0) {
221  if (j == 0) { return fxx; }
222  if (j == 1) { return fxy; }
223  if (j == 2) { return fxz; }
224  } else if (i == 1) {
225  if (j == 0) { return fyx; }
226  if (j == 1) { return fyy; }
227  if (j == 2) { return fyz; }
228  } else if (i == 2) {
229  if (j == 0) { return fzx; }
230  if (j == 1) { return fzy; }
231  if (j == 2) { return fzz; }
232  }
233 
234  Warning("operator()(i,j)", "bad indices (%d , %d)",i,j);
235 
236  return 0.0;
237 }
238 
239 ////////////////////////////////////////////////////////////////////////////////
240 /// Multiplication operator.
241 
243  return TRotation(fxx*b.fxx + fxy*b.fyx + fxz*b.fzx,
244  fxx*b.fxy + fxy*b.fyy + fxz*b.fzy,
245  fxx*b.fxz + fxy*b.fyz + fxz*b.fzz,
246  fyx*b.fxx + fyy*b.fyx + fyz*b.fzx,
247  fyx*b.fxy + fyy*b.fyy + fyz*b.fzy,
248  fyx*b.fxz + fyy*b.fyz + fyz*b.fzz,
249  fzx*b.fxx + fzy*b.fyx + fzz*b.fzx,
250  fzx*b.fxy + fzy*b.fyy + fzz*b.fzy,
251  fzx*b.fxz + fzy*b.fyz + fzz*b.fzz);
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// Constructor for a rotation based on a Quaternion
256 /// if magnitude of quaternion is null, creates identity rotation
257 /// if quaternion is non-unit, creates rotation corresponding to the normalized (unit) quaternion
258 
260 
261  double two_r2 = 2 * Q.fRealPart * Q.fRealPart;
262  double two_x2 = 2 * Q.fVectorPart.X() * Q.fVectorPart.X();
263  double two_y2 = 2 * Q.fVectorPart.Y() * Q.fVectorPart.Y();
264  double two_z2 = 2 * Q.fVectorPart.Z() * Q.fVectorPart.Z();
265  double two_xy = 2 * Q.fVectorPart.X() * Q.fVectorPart.Y();
266  double two_xz = 2 * Q.fVectorPart.X() * Q.fVectorPart.Z();
267  double two_xr = 2 * Q.fVectorPart.X() * Q.fRealPart;
268  double two_yz = 2 * Q.fVectorPart.Y() * Q.fVectorPart.Z();
269  double two_yr = 2 * Q.fVectorPart.Y() * Q.fRealPart;
270  double two_zr = 2 * Q.fVectorPart.Z() * Q.fRealPart;
271 
272  // protect agains zero quaternion
273  double mag2 = Q.QMag2();
274  if (mag2 > 0) {
275 
276  // diago + identity
277  fxx = two_r2 + two_x2;
278  fyy = two_r2 + two_y2;
279  fzz = two_r2 + two_z2;
280 
281  // line 0 column 1 and conjugate
282  fxy = two_xy - two_zr;
283  fyx = two_xy + two_zr;
284 
285  // line 0 column 2 and conjugate
286  fxz = two_xz + two_yr;
287  fzx = two_xz - two_yr;
288 
289  // line 1 column 2 and conjugate
290  fyz = two_yz - two_xr;
291  fzy = two_yz + two_xr;
292 
293  // protect agains non-unit quaternion
294  if (TMath::Abs(mag2-1) > 1e-10) {
295  fxx /= mag2;
296  fyy /= mag2;
297  fzz /= mag2;
298  fxy /= mag2;
299  fyx /= mag2;
300  fxz /= mag2;
301  fzx /= mag2;
302  fyz /= mag2;
303  fzy /= mag2;
304  }
305 
306  // diago : remove identity
307  fxx -= 1;
308  fyy -= 1;
309  fzz -= 1;
310 
311 
312  } else {
313  // Identity
314 
315  fxx = fyy = fzz = 1;
316  fxy = fyx = fxz = fzx = fyz = fzy = 0;
317 
318  }
319 
320 }
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// Rotate along an axis.
324 
326  if (a != 0.0) {
327  Double_t ll = axis.Mag();
328  if (ll == 0.0) {
329  Warning("Rotate(angle,axis)"," zero axis");
330  } else {
331  Double_t sa = TMath::Sin(a), ca = TMath::Cos(a);
332  Double_t dx = axis.X()/ll, dy = axis.Y()/ll, dz = axis.Z()/ll;
333  TRotation m(
334  ca+(1-ca)*dx*dx, (1-ca)*dx*dy-sa*dz, (1-ca)*dx*dz+sa*dy,
335  (1-ca)*dy*dx+sa*dz, ca+(1-ca)*dy*dy, (1-ca)*dy*dz-sa*dx,
336  (1-ca)*dz*dx-sa*dy, (1-ca)*dz*dy+sa*dx, ca+(1-ca)*dz*dz );
337  Transform(m);
338  }
339  }
340  return *this;
341 }
342 
343 ////////////////////////////////////////////////////////////////////////////////
344 /// Rotate around x.
345 
347  Double_t c = TMath::Cos(a);
348  Double_t s = TMath::Sin(a);
349  Double_t x = fyx, y = fyy, z = fyz;
350  fyx = c*x - s*fzx;
351  fyy = c*y - s*fzy;
352  fyz = c*z - s*fzz;
353  fzx = s*x + c*fzx;
354  fzy = s*y + c*fzy;
355  fzz = s*z + c*fzz;
356  return *this;
357 }
358 
359 ////////////////////////////////////////////////////////////////////////////////
360 /// Rotate around y.
361 
363  Double_t c = TMath::Cos(a);
364  Double_t s = TMath::Sin(a);
365  Double_t x = fzx, y = fzy, z = fzz;
366  fzx = c*x - s*fxx;
367  fzy = c*y - s*fxy;
368  fzz = c*z - s*fxz;
369  fxx = s*x + c*fxx;
370  fxy = s*y + c*fxy;
371  fxz = s*z + c*fxz;
372  return *this;
373 }
374 
375 ////////////////////////////////////////////////////////////////////////////////
376 /// Rotate around z.
377 
379  Double_t c = TMath::Cos(a);
380  Double_t s = TMath::Sin(a);
381  Double_t x = fxx, y = fxy, z = fxz;
382  fxx = c*x - s*fyx;
383  fxy = c*y - s*fyy;
384  fxz = c*z - s*fyz;
385  fyx = s*x + c*fyx;
386  fyy = s*y + c*fyy;
387  fyz = s*z + c*fyz;
388  return *this;
389 }
390 
391 ////////////////////////////////////////////////////////////////////////////////
392 /// Rotate axes.
393 
395  const TVector3 &newY,
396  const TVector3 &newZ) {
397  Double_t del = 0.001;
398  TVector3 w = newX.Cross(newY);
399 
400  if (TMath::Abs(newZ.X()-w.X()) > del ||
401  TMath::Abs(newZ.Y()-w.Y()) > del ||
402  TMath::Abs(newZ.Z()-w.Z()) > del ||
403  TMath::Abs(newX.Mag2()-1.) > del ||
404  TMath::Abs(newY.Mag2()-1.) > del ||
405  TMath::Abs(newZ.Mag2()-1.) > del ||
406  TMath::Abs(newX.Dot(newY)) > del ||
407  TMath::Abs(newY.Dot(newZ)) > del ||
408  TMath::Abs(newZ.Dot(newX)) > del) {
409  Warning("RotateAxes","bad axis vectors");
410  return *this;
411  } else {
412  return Transform(TRotation(newX.X(), newY.X(), newZ.X(),
413  newX.Y(), newY.Y(), newZ.Y(),
414  newX.Z(), newY.Z(), newZ.Z()));
415  }
416 }
417 
418 ////////////////////////////////////////////////////////////////////////////////
419 /// Return Phi.
420 
422  return (fyx == 0.0 && fxx == 0.0) ? 0.0 : TMath::ATan2(fyx,fxx);
423 }
424 
425 ////////////////////////////////////////////////////////////////////////////////
426 /// Return Phi.
427 
429  return (fyy == 0.0 && fxy == 0.0) ? 0.0 : TMath::ATan2(fyy,fxy);
430 }
431 
432 ////////////////////////////////////////////////////////////////////////////////
433 /// Return Phi.
434 
436  return (fyz == 0.0 && fxz == 0.0) ? 0.0 : TMath::ATan2(fyz,fxz);
437 }
438 
439 ////////////////////////////////////////////////////////////////////////////////
440 /// Return Theta.
441 
443  return TMath::ACos(fzx);
444 }
445 
446 ////////////////////////////////////////////////////////////////////////////////
447 /// Return Theta.
448 
450  return TMath::ACos(fzy);
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Return Theta.
455 
457  return TMath::ACos(fzz);
458 }
459 
460 ////////////////////////////////////////////////////////////////////////////////
461 /// Rotation defined by an angle and a vector.
462 
463 void TRotation::AngleAxis(Double_t &angle, TVector3 &axis) const {
464  Double_t cosa = 0.5*(fxx+fyy+fzz-1);
465  Double_t cosa1 = 1-cosa;
466  if (cosa1 <= 0) {
467  angle = 0;
468  axis = TVector3(0,0,1);
469  } else {
470  Double_t x=0, y=0, z=0;
471  if (fxx > cosa) x = TMath::Sqrt((fxx-cosa)/cosa1);
472  if (fyy > cosa) y = TMath::Sqrt((fyy-cosa)/cosa1);
473  if (fzz > cosa) z = TMath::Sqrt((fzz-cosa)/cosa1);
474  if (fzy < fyz) x = -x;
475  if (fxz < fzx) y = -y;
476  if (fyx < fxy) z = -z;
477  angle = TMath::ACos(cosa);
478  axis = TVector3(x,y,z);
479  }
480 }
481 
482 ////////////////////////////////////////////////////////////////////////////////
483 /// Rotate using the x-convention (Landau and Lifshitz, Goldstein, &c) by
484 /// doing the explicit rotations. This is slightly less efficient than
485 /// directly applying the rotation, but makes the code much clearer. My
486 /// presumption is that this code is not going to be a speed bottle neck.
487 
489  Double_t theta,
490  Double_t psi) {
491  SetToIdentity();
492  RotateZ(phi);
493  RotateX(theta);
494  RotateZ(psi);
495 
496  return *this;
497 }
498 
499 ////////////////////////////////////////////////////////////////////////////////
500 /// Rotate using the y-convention.
501 
503  Double_t theta,
504  Double_t psi) {
505  SetToIdentity();
506  RotateZ(phi);
507  RotateY(theta);
508  RotateZ(psi);
509  return *this;
510 }
511 
512 ////////////////////////////////////////////////////////////////////////////////
513 /// Rotate using the x-convention.
514 
516  Double_t theta,
517  Double_t psi) {
518  TRotation euler;
519  euler.SetXEulerAngles(phi,theta,psi);
520  return Transform(euler);
521 }
522 
523 ////////////////////////////////////////////////////////////////////////////////
524 /// Rotate using the y-convention.
525 
527  Double_t theta,
528  Double_t psi) {
529  TRotation euler;
530  euler.SetYEulerAngles(phi,theta,psi);
531  return Transform(euler);
532 }
533 
534 ////////////////////////////////////////////////////////////////////////////////
535 /// Set XPhi.
536 
539 }
540 
541 ////////////////////////////////////////////////////////////////////////////////
542 /// Set XTheta.
543 
545  SetXEulerAngles(GetXPhi(),theta,GetXPsi());
546 }
547 
548 ////////////////////////////////////////////////////////////////////////////////
549 /// Set XPsi.
550 
553 }
554 
555 ////////////////////////////////////////////////////////////////////////////////
556 /// Set YPhi.
557 
560 }
561 
562 ////////////////////////////////////////////////////////////////////////////////
563 /// Set YTheta.
564 
566  SetYEulerAngles(GetYPhi(),theta,GetYPsi());
567 }
568 
569 ////////////////////////////////////////////////////////////////////////////////
570 /// Set YPsi.
571 
574 }
575 
576 ////////////////////////////////////////////////////////////////////////////////
577 /// Return phi angle.
578 
580  Double_t finalPhi;
581 
582  Double_t s2 = 1.0 - fzz*fzz;
583  if (s2 < 0) {
584  Warning("GetPhi()"," |fzz| > 1 ");
585  s2 = 0;
586  }
587  const Double_t sinTheta = TMath::Sqrt(s2);
588 
589  if (sinTheta != 0) {
590  const Double_t cscTheta = 1/sinTheta;
591  Double_t cosAbsPhi = fzy * cscTheta;
592  if ( TMath::Abs(cosAbsPhi) > 1 ) { // NaN-proofing
593  Warning("GetPhi()","finds | cos phi | > 1");
594  cosAbsPhi = 1;
595  }
596  const Double_t absPhi = TMath::ACos(cosAbsPhi);
597  if (fzx > 0) {
598  finalPhi = absPhi;
599  } else if (fzx < 0) {
600  finalPhi = -absPhi;
601  } else if (fzy > 0) {
602  finalPhi = 0.0;
603  } else {
604  finalPhi = TMath::Pi();
605  }
606  } else { // sinTheta == 0 so |Fzz| = 1
607  const Double_t absPhi = .5 * TMath::ACos (fxx);
608  if (fxy > 0) {
609  finalPhi = -absPhi;
610  } else if (fxy < 0) {
611  finalPhi = absPhi;
612  } else if (fxx>0) {
613  finalPhi = 0.0;
614  } else {
615  finalPhi = fzz * TMath::PiOver2();
616  }
617  }
618  return finalPhi;
619 }
620 
621 ////////////////////////////////////////////////////////////////////////////////
622 /// Return YPhi.
623 
625  return GetXPhi() + TMath::Pi()/2.0;
626 }
627 
628 ////////////////////////////////////////////////////////////////////////////////
629 /// Return XTheta.
630 
632  return ThetaZ();
633 }
634 
635 ////////////////////////////////////////////////////////////////////////////////
636 /// Return YTheta.
637 
639  return ThetaZ();
640 }
641 
642 ////////////////////////////////////////////////////////////////////////////////
643 /// Get psi angle.
644 
646  double finalPsi = 0.0;
647 
648  Double_t s2 = 1.0 - fzz*fzz;
649  if (s2 < 0) {
650  Warning("GetPsi()"," |fzz| > 1 ");
651  s2 = 0;
652  }
653  const Double_t sinTheta = TMath::Sqrt(s2);
654 
655  if (sinTheta != 0) {
656  const Double_t cscTheta = 1/sinTheta;
657  Double_t cosAbsPsi = - fyz * cscTheta;
658  if ( TMath::Abs(cosAbsPsi) > 1 ) { // NaN-proofing
659  Warning("GetPsi()","| cos psi | > 1 ");
660  cosAbsPsi = 1;
661  }
662  const Double_t absPsi = TMath::ACos(cosAbsPsi);
663  if (fxz > 0) {
664  finalPsi = absPsi;
665  } else if (fxz < 0) {
666  finalPsi = -absPsi;
667  } else {
668  finalPsi = (fyz < 0) ? 0 : TMath::Pi();
669  }
670  } else { // sinTheta == 0 so |Fzz| = 1
671  Double_t absPsi = fxx;
672  if ( TMath::Abs(fxx) > 1 ) { // NaN-proofing
673  Warning("GetPsi()","| fxx | > 1 ");
674  absPsi = 1;
675  }
676  absPsi = .5 * TMath::ACos (absPsi);
677  if (fyx > 0) {
678  finalPsi = absPsi;
679  } else if (fyx < 0) {
680  finalPsi = -absPsi;
681  } else {
682  finalPsi = (fxx > 0) ? 0 : TMath::PiOver2();
683  }
684  }
685  return finalPsi;
686 }
687 
688 ////////////////////////////////////////////////////////////////////////////////
689 /// Return YPsi.
690 
692  return GetXPsi() - TMath::Pi()/2;
693 }
694 
695 ////////////////////////////////////////////////////////////////////////////////
696 /// Set X axis.
697 
699  const TVector3& xyPlane) {
700  TVector3 xAxis(xyPlane);
701  TVector3 yAxis;
702  TVector3 zAxis(axis);
703  MakeBasis(xAxis,yAxis,zAxis);
704  fxx = zAxis.X(); fyx = zAxis.Y(); fzx = zAxis.Z();
705  fxy = xAxis.X(); fyy = xAxis.Y(); fzy = xAxis.Z();
706  fxz = yAxis.X(); fyz = yAxis.Y(); fzz = yAxis.Z();
707  return *this;
708 }
709 
710 ////////////////////////////////////////////////////////////////////////////////
711 /// Set X axis.
712 
714  TVector3 xyPlane(0.0,1.0,0.0);
715  return SetXAxis(axis,xyPlane);
716 }
717 
718 ////////////////////////////////////////////////////////////////////////////////
719 /// Set Y axis.
720 
722  const TVector3& yzPlane) {
723  TVector3 xAxis(yzPlane);
724  TVector3 yAxis;
725  TVector3 zAxis(axis);
726  MakeBasis(xAxis,yAxis,zAxis);
727  fxx = yAxis.X(); fyx = yAxis.Y(); fzx = yAxis.Z();
728  fxy = zAxis.X(); fyy = zAxis.Y(); fzy = zAxis.Z();
729  fxz = xAxis.X(); fyz = xAxis.Y(); fzz = xAxis.Z();
730  return *this;
731 }
732 
733 ////////////////////////////////////////////////////////////////////////////////
734 /// Set Y axis.
735 
737  TVector3 yzPlane(0.0,0.0,1.0);
738  return SetYAxis(axis,yzPlane);
739 }
740 
741 ////////////////////////////////////////////////////////////////////////////////
742 /// Set Z axis.
743 
745  const TVector3& zxPlane) {
746  TVector3 xAxis(zxPlane);
747  TVector3 yAxis;
748  TVector3 zAxis(axis);
749  MakeBasis(xAxis,yAxis,zAxis);
750  fxx = xAxis.X(); fyx = xAxis.Y(); fzx = xAxis.Z();
751  fxy = yAxis.X(); fyy = yAxis.Y(); fzy = yAxis.Z();
752  fxz = zAxis.X(); fyz = zAxis.Y(); fzz = zAxis.Z();
753  return *this;
754 }
755 
756 ////////////////////////////////////////////////////////////////////////////////
757 /// Set Z axis.
758 
760  TVector3 zxPlane(1.0,0.0,0.0);
761  return SetZAxis(axis,zxPlane);
762 }
763 
764 ////////////////////////////////////////////////////////////////////////////////
765 /// Make the Z axis into a unit variable.
766 
768  TVector3& yAxis,
769  TVector3& zAxis) const {
770  Double_t zmag = zAxis.Mag();
771  if (zmag<TOLERANCE) {
772  Warning("MakeBasis(X,Y,Z)","non-zero Z Axis is required");
773  }
774  zAxis *= (1.0/zmag);
775 
776  Double_t xmag = xAxis.Mag();
777  if (xmag<TOLERANCE*zmag) {
778  xAxis = zAxis.Orthogonal();
779  xmag = 1.0;
780  }
781 
782  // Find the Y axis
783  yAxis = zAxis.Cross(xAxis)*(1.0/xmag);
784  Double_t ymag = yAxis.Mag();
785  if (ymag<TOLERANCE*zmag) {
786  yAxis = zAxis.Orthogonal();
787  } else {
788  yAxis *= (1.0/ymag);
789  }
790 
791  xAxis = yAxis.Cross(zAxis);
792 }
Double_t X() const
Definition: TVector3.h:224
Double_t Dot(const TVector3 &) const
Definition: TVector3.h:339
TRotation & RotateYEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the y-convention.
Definition: TRotation.cxx:526
Double_t PhiY() const
Return Phi.
Definition: TRotation.cxx:428
return c
TRotation & RotateZ(Double_t)
Rotate around z.
Definition: TRotation.cxx:378
Double_t fyy
Definition: TRotation.h:184
TVector3 fVectorPart
Definition: TQuaternion.h:115
Double_t fzy
Definition: TRotation.h:184
Quaternion is a 4-component mathematic object quite convenient when dealing with space rotation (or r...
Definition: TQuaternion.h:15
TRotation & RotateX(Double_t)
Rotate around x.
Definition: TRotation.cxx:346
Double_t fzx
Definition: TRotation.h:184
Double_t Mag2() const
Definition: TVector3.h:347
Double_t operator()(int, int) const
Dereferencing operator const.
Definition: TRotation.cxx:219
Double_t GetXPsi(void) const
Get psi angle.
Definition: TRotation.cxx:645
TArc * a
Definition: textangle.C:12
void SetYPsi(Double_t)
Set YPsi.
Definition: TRotation.cxx:572
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
TRotation & SetXAxis(const TVector3 &axis)
Set X axis.
Definition: TRotation.cxx:713
TRotation & RotateAxes(const TVector3 &newX, const TVector3 &newY, const TVector3 &newZ)
Rotate axes.
Definition: TRotation.cxx:394
Double_t Mag() const
Definition: TVector3.h:94
Double_t fxy
Definition: TRotation.h:184
Double_t PhiX() const
Return Phi.
Definition: TRotation.cxx:421
Double_t x[n]
Definition: legend1.C:17
void SetXPhi(Double_t)
Set XPhi.
Definition: TRotation.cxx:537
Double_t Y() const
Definition: TVector3.h:225
TRotation & SetToIdentity()
Definition: TRotation.h:253
Double_t fzz
Definition: TRotation.h:184
void SetYTheta(Double_t)
Set YTheta.
Definition: TRotation.cxx:565
Double_t ATan2(Double_t, Double_t)
Definition: TMath.h:454
void SetXTheta(Double_t)
Set XTheta.
Definition: TRotation.cxx:544
TRotation & Rotate(Double_t, const TVector3 &)
Rotate along an axis.
Definition: TRotation.cxx:325
Double_t fyx
Definition: TRotation.h:184
TVector3 is a general three vector class, which can be used for the description of different vectors ...
Definition: TVector3.h:30
TRotation & Transform(const TRotation &)
Definition: TRotation.h:269
TVector3 Cross(const TVector3 &) const
Definition: TVector3.h:343
Double_t Z() const
Definition: TVector3.h:226
The TRotation class describes a rotation of objects of the TVector3 class.
Definition: TRotation.h:22
TRotation & SetYAxis(const TVector3 &axis)
Set Y axis.
Definition: TRotation.cxx:736
TMarker * m
Definition: textangle.C:8
Double_t fxx
Definition: TRotation.h:184
Double_t ACos(Double_t)
Definition: TMath.h:445
TRotation & RotateXEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the x-convention.
Definition: TRotation.cxx:515
Double_t PhiZ() const
Return Phi.
Definition: TRotation.cxx:435
Double_t Cos(Double_t)
Definition: TMath.h:424
void AngleAxis(Double_t &, TVector3 &) const
Rotation defined by an angle and a vector.
Definition: TRotation.cxx:463
Double_t Pi()
Definition: TMath.h:44
Double_t GetYTheta(void) const
Return YTheta.
Definition: TRotation.cxx:638
void SetYPhi(Double_t)
Set YPhi.
Definition: TRotation.cxx:558
#define ClassImp(name)
Definition: Rtypes.h:279
Double_t GetYPhi(void) const
Return YPhi.
Definition: TRotation.cxx:624
double Double_t
Definition: RtypesCore.h:55
Double_t GetXPhi(void) const
Return phi angle.
Definition: TRotation.cxx:579
TVector3 Orthogonal() const
Definition: TVector3.h:350
Double_t y[n]
Definition: legend1.C:17
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
TRotation & RotateY(Double_t)
Rotate around y.
Definition: TRotation.cxx:362
Mother of all ROOT objects.
Definition: TObject.h:37
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
TRotation()
Constructor.
Definition: TRotation.cxx:196
TRotation & SetYEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the y-convention.
Definition: TRotation.cxx:502
Double_t PiOver2()
Definition: TMath.h:46
Double_t fxz
Definition: TRotation.h:184
Double_t fRealPart
Definition: TQuaternion.h:114
void MakeBasis(TVector3 &xAxis, TVector3 &yAxis, TVector3 &zAxis) const
Make the Z axis into a unit variable.
Definition: TRotation.cxx:767
Double_t Sin(Double_t)
Definition: TMath.h:421
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
TRotation & SetZAxis(const TVector3 &axis)
Set Z axis.
Definition: TRotation.cxx:759
TVector3 operator*(const TVector3 &) const
Definition: TRotation.h:259
#define TOLERANCE
Definition: TRotation.cxx:191
Double_t ThetaX() const
Return Theta.
Definition: TRotation.cxx:442
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
Double_t ThetaY() const
Return Theta.
Definition: TRotation.cxx:449
Double_t GetXTheta(void) const
Return XTheta.
Definition: TRotation.cxx:631
Double_t fyz
Definition: TRotation.h:184
Double_t QMag2() const
Definition: TQuaternion.h:104
void SetXPsi(Double_t)
Set XPsi.
Definition: TRotation.cxx:551
static double Q[]
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:911
Double_t GetYPsi(void) const
Return YPsi.
Definition: TRotation.cxx:691
TRotation & SetXEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the x-convention (Landau and Lifshitz, Goldstein, &c) by doing the explicit rotations...
Definition: TRotation.cxx:488
Double_t ThetaZ() const
Return Theta.
Definition: TRotation.cxx:456