ROOT   Reference Guide
Searching...
No Matches
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 \legacy{TRotation, Consider using instead ROOT::Math::Rotation3D.}
6 \ingroup Physics
7
8The TRotation class describes a rotation of objects of the TVector3 class.
9It is a 3*3 matrix of Double_t:
10
11~~~
12| xx xy xz |
13| yx yy yz |
14| zx zy zz |
15~~~
16
17It describes a so called active rotation, i.e. rotation of objects inside
18a static system of coordinates. In case you want to rotate the frame and
19want to know the coordinates of objects in the rotated system, you should
20apply the inverse rotation to the objects. If you want to transform coordinates
21from the rotated frame to the original frame you have to apply the direct
22transformation.
23
24A rotation around a specified axis means counterclockwise rotation around
25the positive direction of the axis.
26
27
28### Declaration, Access, Comparisons
29
30~~~
31 TRotation r; // r initialized as identity
32 TRotation m(r); // m = r
33~~~
34
35There is no direct way to set the matrix elements - to ensure that
36a TRotation object always describes a real rotation. But you can get the
37values by the member functions XX()..ZZ() or the (,)
38operator:
39
40~~~
41 Double_t xx = r.XX(); // the same as xx=r(0,0)
42 xx = r(0,0);
43
44 if (r==m) {...} // test for equality
45 if (r!=m) {..} // test for inequality
46 if (r.IsIdentity()) {...} // test for identity
47~~~
48
49### Rotation around axes
50The following matrices describe counterclockwise rotations around coordinate
51axes
52
53~~~
54 | 1 0 0 |
55Rx(a) = | 0 cos(a) -sin(a) |
56 | 0 sin(a) cos(a) |
57
58 | cos(a) 0 sin(a) |
59Ry(a) = | 0 1 0 |
60 | -sin(a) 0 cos(a) |
61
62 | cos(a) -sin(a) 0 |
63Rz(a) = | sin(a) cos(a) 0 |
64 | 0 0 1 |
65~~~
66
67and are implemented as member functions RotateX(), RotateY() and RotateZ():
68
69~~~
70 r.RotateX(TMath::Pi()); // rotation around the x-axis
71~~~
72
73### Rotation around arbitrary axis
74The member function Rotate() allows to rotate around an arbitrary vector
75(not necessary a unit one) and returns the result.
76
77~~~
78 r.Rotate(TMath::Pi()/3,TVector3(3,4,5));
79~~~
80
81It is possible to find a unit vector and an angle, which describe the
82same rotation as the current one:
83
84~~~
85 Double_t angle;
86 TVector3 axis;
87 r.GetAngleAxis(angle,axis);
88~~~
89
90### Rotation of local axes
91Member function RotateAxes() adds a rotation of local axes to
92the current rotation and returns the result:
93
94~~~
95 TVector3 newX(0,1,0);
96 TVector3 newY(0,0,1);
97 TVector3 newZ(1,0,0);
98 a.RotateAxes(newX,newY,newZ);
99~~~
100
101Member functions ThetaX(), ThetaY(), ThetaZ(),
102PhiX(), PhiY(),PhiZ() return azimuth and polar
103angles of the rotated axes:
104
105~~~
106 Double_t tx,ty,tz,px,py,pz;
107 tx= a.ThetaX();
108 ...
109 pz= a.PhiZ();
110~~~
111
112### Setting The Rotations
113The member function SetToIdentity() will set the rotation object
114to the identity (no rotation).
115
116With a minor caveat, the Euler angles of the rotation may be set using
117SetXEulerAngles() or individually set with SetXPhi(),
118SetXTheta(), and SetXPsi(). These routines set the Euler
119angles using the X-convention which is defined by a rotation about the Z-axis,
120about the new X-axis, and about the new Z-axis. This is the convention used
121in Landau and Lifshitz, Goldstein and other common physics texts. The
122Y-convention Euler angles can be set with SetYEulerAngles(),
123SetYPhi(), SetYTheta(), and SetYPsi(). The caveat
124is that Euler angles usually define the rotation of the new coordinate system
125with respect to the original system, however, the TRotation class specifies
126the rotation of the object in the original system (an active rotation). To
127recover the usual Euler rotations (ie. rotate the system not the object), you
128must take the inverse of the rotation.
129
130The member functions SetXAxis(), SetYAxis(), and
131SetZAxis() will create a rotation which rotates the requested axis
132of the object to be parallel to a vector. If used with one argument, the
133rotation about that axis is arbitrary. If used with two arguments, the
134second variable defines the XY, YZ, or ZX
135respectively.
136
137
138### Inverse rotation
139
140~~~
141 TRotation a,b;
142 ...
143 b = a.Inverse(); // b is inverse of a, a is unchanged
144 b = a.Invert(); // invert a and set b = a
145~~~
146
147### Compound Rotations
148The operator * has been implemented in a way that follows the
149mathematical notation of a product of the two matrices which describe the
150two consecutive rotations. Therefore the second rotation should be placed
151first:
152
153~~~
154 r = r2 * r1;
155~~~
156
157### Rotation of TVector3
158The TRotation class provides an operator * which allows to express
159a rotation of a TVector3 analog to the mathematical notation
160
161~~~
162 | x' | | xx xy xz | | x |
163 | y' | = | yx yy yz | | y |
164 | z' | | zx zy zz | | z |
165~~~
166
167e.g.:
168
169~~~
170 TVector3 v(1,1,1);
171 v = r * v;
172~~~
173
174You can also use the Transform() member function or the operator *= of the
175TVector3 class:
176
177~~~
178 TVector3 v;
179 TRotation r;
180 v.Transform(r);
181 v *= r; //Attention v = r * v
182~~~
183*/
184
185#include "TRotation.h"
186#include "TMath.h"
187#include "TQuaternion.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
219Double_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 against 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 against 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
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
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
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) {
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
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) {
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) {
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
546}
547
548////////////////////////////////////////////////////////////////////////////////
549/// Set XPsi.
550
553}
554
555////////////////////////////////////////////////////////////////////////////////
556/// Set YPhi.
557
560}
561
562////////////////////////////////////////////////////////////////////////////////
563/// Set YTheta.
564
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}
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t del
Option_t Option_t TPoint TPoint angle
#define TOLERANCE
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
<div class="legacybox"><h2>Legacy Code</h2> TQuaternion is a legacy interface: there will be no bug f...
Definition TQuaternion.h:11
Double_t QMag2() const
TVector3 fVectorPart
Double_t fRealPart
<div class="legacybox"><h2>Legacy Code</h2> TRotation is a legacy interface: there will be no bug fix...
Definition TRotation.h:20
Double_t fzz
Definition TRotation.h:182
Double_t fyy
Definition TRotation.h:182
TRotation & SetToIdentity()
Definition TRotation.h:251
TRotation & SetZAxis(const TVector3 &axis)
Set Z axis.
Double_t PhiY() const
Return Phi.
TRotation & Rotate(Double_t, const TVector3 &)
Rotate along an axis.
Double_t fzy
Definition TRotation.h:182
void SetXPhi(Double_t)
Set XPhi.
Double_t GetYPhi(void) const
Return YPhi.
TRotation()
Constructor.
Double_t operator()(int, int) const
Dereferencing operator const.
Double_t ThetaY() const
Return Theta.
TRotation & RotateYEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the y-convention.
void SetYPhi(Double_t)
Set YPhi.
TRotation & SetYAxis(const TVector3 &axis)
Set Y axis.
Double_t fyx
Definition TRotation.h:182
Double_t GetXPsi(void) const
Get psi angle.
void SetXPsi(Double_t)
Set XPsi.
Double_t PhiX() const
Return Phi.
Double_t fxz
Definition TRotation.h:182
TRotation & Transform(const TRotation &)
Definition TRotation.h:267
TRotation & RotateY(Double_t)
Rotate around y.
Double_t fyz
Definition TRotation.h:182
Double_t PhiZ() const
Return Phi.
TRotation & RotateZ(Double_t)
Rotate around z.
TVector3 operator*(const TVector3 &) const
Definition TRotation.h:257
Double_t GetYPsi(void) const
Return YPsi.
Double_t GetYTheta(void) const
Return YTheta.
TRotation & RotateXEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the x-convention.
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.
void AngleAxis(Double_t &, TVector3 &) const
Rotation defined by an angle and a vector.
Double_t ThetaZ() const
Return Theta.
void SetYPsi(Double_t)
Set YPsi.
void SetYTheta(Double_t)
Set YTheta.
Double_t fxx
Definition TRotation.h:182
TRotation & SetYEulerAngles(Double_t phi, Double_t theta, Double_t psi)
Rotate using the y-convention.
void MakeBasis(TVector3 &xAxis, TVector3 &yAxis, TVector3 &zAxis) const
Make the Z axis into a unit variable.
TRotation & RotateAxes(const TVector3 &newX, const TVector3 &newY, const TVector3 &newZ)
Rotate axes.
void SetXTheta(Double_t)
Set XTheta.
Double_t GetXPhi(void) const
Return phi angle.
TRotation & SetXAxis(const TVector3 &axis)
Set X axis.
Double_t GetXTheta(void) const
Return XTheta.
Double_t fzx
Definition TRotation.h:182
Double_t ThetaX() const
Return Theta.
Double_t fxy
Definition TRotation.h:182
TRotation & RotateX(Double_t)
Rotate around x.
Double_t Z() const
Definition TVector3.h:218
Double_t Y() const
Definition TVector3.h:217
Double_t Dot(const TVector3 &) const
Definition TVector3.h:331
Double_t Mag2() const
Definition TVector3.h:339
Double_t X() const
Definition TVector3.h:216
TVector3 Orthogonal() const
Definition TVector3.h:342
Double_t Mag() const
Definition TVector3.h:86
TVector3 Cross(const TVector3 &) const
Definition TVector3.h:335
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:632
constexpr Double_t PiOver2()
Definition TMath.h:51
Double_t ATan2(Double_t y, Double_t x)
Returns the principal value of the arc tangent of y/x, expressed in radians.
Definition TMath.h:646
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:594
constexpr Double_t Pi()
Definition TMath.h:37
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:588
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
TMarker m
Definition textangle.C:8