ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RotationA.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RotationA.cc
1 // -*- C++ -*-
2 // ---------------------------------------------------------------------------
3 //
4 // This file is a part of the CLHEP - a Class Library for High Energy Physics.
5 //
6 // This is the implementation of those methods of the HepRotation class which
7 // were introduced when ZOOM PhysicsVectors was merged in, and which involve
8 // the angle/axis representation of a Rotation.
9 //
10 
11 #ifdef GNUPRAGMA
12 #pragma implementation
13 #endif
14 
15 #include "CLHEP/Vector/Rotation.h"
17 
18 #include <iostream>
19 #include <cmath>
20 
21 namespace CLHEP {
22 
23 // ---------- Constructors and Assignment:
24 
25 // axis and angle
26 
27 HepRotation & HepRotation::set( const Hep3Vector & aaxis, double ddelta ) {
28 
29  double sinDelta = std::sin(ddelta), cosDelta = std::cos(ddelta);
30  double oneMinusCosDelta = 1.0 - cosDelta;
31 
32  Hep3Vector u = aaxis.unit();
33 
34  double uX = u.getX();
35  double uY = u.getY();
36  double uZ = u.getZ();
37 
38  rxx = oneMinusCosDelta * uX * uX + cosDelta;
39  rxy = oneMinusCosDelta * uX * uY - sinDelta * uZ;
40  rxz = oneMinusCosDelta * uX * uZ + sinDelta * uY;
41 
42  ryx = oneMinusCosDelta * uY * uX + sinDelta * uZ;
43  ryy = oneMinusCosDelta * uY * uY + cosDelta;
44  ryz = oneMinusCosDelta * uY * uZ - sinDelta * uX;
45 
46  rzx = oneMinusCosDelta * uZ * uX - sinDelta * uY;
47  rzy = oneMinusCosDelta * uZ * uY + sinDelta * uX;
48  rzz = oneMinusCosDelta * uZ * uZ + cosDelta;
49 
50  return *this;
51 
52 } // HepRotation::set(axis, delta)
53 
54 HepRotation::HepRotation ( const Hep3Vector & aaxis, double ddelta )
55 {
56  set( aaxis, ddelta );
57 }
59  return set ( ax.axis(), ax.delta() );
60 }
62 {
63  set ( ax.axis(), ax.delta() );
64 }
65 
66 double HepRotation::delta() const {
67 
68  double cosdelta = (rxx + ryy + rzz - 1.0) / 2.0;
69  if (cosdelta > 1.0) {
70  return 0;
71  } else if (cosdelta < -1.0) {
72  return CLHEP::pi;
73  } else {
74  return std::acos( cosdelta ); // Already safe due to the cosdelta > 1 check
75  }
76 
77 } // delta()
78 
80 
81  const double eps = 1e-15;
82 
83  double Ux = rzy - ryz;
84  double Uy = rxz - rzx;
85  double Uz = ryx - rxy;
86  if (std::abs(Ux) < eps && std::abs(Uy) < eps && std::abs(Uz) < eps) {
87 
88  double cosdelta = (rxx + ryy + rzz - 1.0) / 2.0;
89  if (cosdelta > 0.0) return Hep3Vector(0,0,1); // angle = 0, any axis is good
90 
91  double mxx = (rxx + 1)/2;
92  double myy = (ryy + 1)/2;
93  double mzz = (rzz + 1)/2;
94  double mxy = (rxy + ryx)/4;
95  double mxz = (rxz + rzx)/4;
96  double myz = (ryz + rzy)/4;
97  double x, y, z;
98 
99  if (mxx > ryy && mxx > rzz) {
100  x = std::sqrt(mxx);
101  if (rzy - ryz < 0) x = -x;
102  y = mxy/x;
103  z = mxz/x;
104  return Hep3Vector( x, y, z ).unit();
105  } else if (myy > mzz) {
106  y = std::sqrt(myy);
107  if (rxz - rzx < 0) y = -y;
108  x = mxy/y;
109  z = myz/y;
110  return Hep3Vector( x, y, z ).unit();
111  } else {
112  z = std::sqrt(mzz);
113  if (ryx - rxy < 0) z = -z;
114  x = mxz/z;
115  y = myz/z;
116  return Hep3Vector( x, y, z ).unit();
117  }
118  } else {
119  return Hep3Vector( Ux, Uy, Uz ).unit();
120  }
121 
122 } // axis()
123 
125 
126  return HepAxisAngle (axis(), delta());
127 
128 } // axisAngle()
129 
130 
131 void HepRotation::setAxis (const Hep3Vector & aaxis) {
132  set ( aaxis, delta() );
133 }
134 
135 void HepRotation::setDelta (double ddelta) {
136  set ( axis(), ddelta );
137 }
138 
139 } // namespace CLHEP