Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/clhep/src/RotationE.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/clhep/src/RotationE.cc (Version 11.3.0) and /externals/clhep/src/RotationE.cc (Version 9.2.p4)


  1 // -*- C++ -*-                                      1 
  2 // -------------------------------------------    
  3 //                                                
  4 // This file is a part of the CLHEP - a Class     
  5 //                                                
  6 // This is the implementation of methods of th    
  7 // were introduced when ZOOM PhysicsVectors wa    
  8 // Euler Angles representation.                   
  9 //                                                
 10 // Apr 28, 2003  mf  Modified way of computing    
 11 //                   answers in the case where    
 12 //                   the matrix is not a perfe    
 13                                                   
 14 #include "CLHEP/Vector/Rotation.h"                
 15 #include "CLHEP/Vector/EulerAngles.h"             
 16 #include "CLHEP/Units/PhysicalConstants.h"        
 17                                                   
 18 #include <cmath>                                  
 19 #include <iostream>                               
 20                                                   
 21 namespace CLHEP  {                                
 22                                                   
 23 static inline double safe_acos (double x) {       
 24   if (std::abs(x) <= 1.0) return std::acos(x);    
 25   return ( (x>0) ? 0 : CLHEP::pi );               
 26 }                                                 
 27                                                   
 28 // ----------  Constructors and Assignment:       
 29                                                   
 30 // Euler angles                                   
 31                                                   
 32 HepRotation & HepRotation::set(double phi1, do    
 33                                                   
 34   double sinPhi   = std::sin( phi1   ), cosPhi    
 35   double sinTheta = std::sin( theta1 ), cosThe    
 36   double sinPsi   = std::sin( psi1   ), cosPsi    
 37                                                   
 38   rxx =   cosPsi * cosPhi - cosTheta * sinPhi     
 39   rxy =   cosPsi * sinPhi + cosTheta * cosPhi     
 40   rxz =   sinPsi * sinTheta;                      
 41                                                   
 42   ryx = - sinPsi * cosPhi - cosTheta * sinPhi     
 43   ryy = - sinPsi * sinPhi + cosTheta * cosPhi     
 44   ryz =   cosPsi * sinTheta;                      
 45                                                   
 46   rzx =   sinTheta * sinPhi;                      
 47   rzy = - sinTheta * cosPhi;                      
 48   rzz =   cosTheta;                               
 49                                                   
 50   return  *this;                                  
 51                                                   
 52 }  // Rotation::set(phi, theta, psi)              
 53                                                   
 54 HepRotation::HepRotation( double phi1, double     
 55 {                                                 
 56   set (phi1, theta1, psi1);                       
 57 }                                                 
 58 HepRotation & HepRotation::set( const HepEuler    
 59   return set(e.phi(), e.theta(), e.psi());        
 60 }                                                 
 61 HepRotation::HepRotation ( const HepEulerAngle    
 62 {                                                 
 63   set(e.phi(), e.theta(), e.psi());               
 64 }                                                 
 65                                                   
 66                                                   
 67 double HepRotation::phi  () const {               
 68                                                   
 69   double s2 =  1.0 - rzz*rzz;                     
 70   if (s2 < 0) {                                   
 71     std::cerr << "HepRotation::phi() - "          
 72         << "HepRotation::phi() finds | rzz | >    
 73     s2 = 0;                                       
 74   }                                               
 75   const double sinTheta = std::sqrt( s2 );        
 76                                                   
 77   if (sinTheta < .01) { // For theta close to     
 78         // algorithm to get all three Euler an    
 79     HepEulerAngles ea = eulerAngles();            
 80     return ea.phi();                              
 81   }                                               
 82                                                   
 83   const double cscTheta = 1/sinTheta;             
 84   double cosabsphi =  - rzy * cscTheta;           
 85   if ( std::fabs(cosabsphi) > 1 ) { // NaN-pro    
 86     std::cerr << "HepRotation::phi() - "          
 87       << "HepRotation::phi() finds | cos phi |    
 88     cosabsphi = 1;                                
 89   }                                               
 90   const double absPhi = std::acos ( cosabsphi     
 91   if (rzx > 0) {                                  
 92     return   absPhi;                              
 93   } else if (rzx < 0) {                           
 94     return  -absPhi;                              
 95   } else {                                        
 96     return  (rzy < 0) ? 0 : CLHEP::pi;            
 97   }                                               
 98                                                   
 99 } // phi()                                        
100                                                   
101 double HepRotation::theta() const {               
102                                                   
103   return  safe_acos( rzz );                       
104                                                   
105 } // theta()                                      
106                                                   
107 double HepRotation::psi  () const {               
108                                                   
109   double sinTheta;                                
110   if ( std::fabs(rzz) > 1 ) { // NaN-proofing     
111     std::cerr << "HepRotation::psi() - "          
112       << "HepRotation::psi() finds | rzz | > 1    
113     sinTheta = 0;                                 
114   } else {                                        
115     sinTheta = std::sqrt( 1.0 - rzz*rzz );        
116   }                                               
117                                                   
118   if (sinTheta < .01) { // For theta close to     
119         // algorithm to get all three Euler an    
120     HepEulerAngles ea = eulerAngles();            
121     return ea.psi();                              
122   }                                               
123                                                   
124   const double cscTheta = 1/sinTheta;             
125   double cosabspsi =  ryz * cscTheta;             
126   if ( std::fabs(cosabspsi) > 1 ) { // NaN-pro    
127     std::cerr << "HepRotation::psi() - "          
128       << "HepRotation::psi() finds | cos psi |    
129     cosabspsi = 1;                                
130   }                                               
131   const double absPsi = std::acos ( cosabspsi     
132   if (rxz > 0) {                                  
133     return   absPsi;                              
134   } else if (rxz < 0) {                           
135     return  -absPsi;                              
136   } else {                                        
137     return  (ryz > 0) ? 0 : CLHEP::pi;            
138   }                                               
139                                                   
140 } // psi()                                        
141                                                   
142 // Helpers for eulerAngles():                     
143                                                   
144 static                                            
145 void correctByPi ( double& psi1, double& phi1     
146   if (psi1 > 0) {                                 
147     psi1 -= CLHEP::pi;                            
148   } else {                                        
149     psi1 += CLHEP::pi;                            
150   }                                               
151   if (phi1 > 0) {                                 
152     phi1 -= CLHEP::pi;                            
153   } else {                                        
154     phi1 += CLHEP::pi;                            
155   }                                               
156 }                                                 
157                                                   
158 static                                            
159 void correctPsiPhi ( double rxz, double rzx, d    
160          double& psi1, double& phi1 ) {           
161                                                   
162   // set up quatities which would be positive     
163   // psi1 and phi1 were positive:                 
164   double w[4];                                    
165   w[0] = rxz; w[1] = rzx; w[2] = ryz; w[3] = -    
166                                                   
167   // find biggest relevant term, which is the     
168   double maxw = std::abs(w[0]);                   
169   int imax = 0;                                   
170   for (int i = 1; i < 4; ++i) {                   
171     if (std::abs(w[i]) > maxw) {                  
172       maxw = std::abs(w[i]);                      
173       imax = i;                                   
174     }                                             
175   }                                               
176   // Determine if the correction needs to be a    
177   // different depending on whether a sine or     
178   switch (imax) {                                 
179     case 0:                                       
180       if (w[0] > 0 && psi1 < 0)           corr    
181       if (w[0] < 0 && psi1 > 0)           corr    
182       break;                                      
183     case 1:                                       
184       if (w[1] > 0 && phi1 < 0)           corr    
185       if (w[1] < 0 && phi1 > 0)           corr    
186       break;                                      
187     case 2:                                       
188       if (w[2] > 0 && std::abs(psi1) > CLHEP::    
189       if (w[2] < 0 && std::abs(psi1) < CLHEP::    
190       break;                                      
191     case 3:                                       
192       if (w[3] > 0 && std::abs(phi1) > CLHEP::    
193       if (w[3] < 0 && std::abs(phi1) < CLHEP::    
194       break;                                      
195   }                                               
196 }                                                 
197                                                   
198 HepEulerAngles HepRotation::eulerAngles() cons    
199                                                   
200   // Please see the mathematical justification    
201                                                   
202   double phi1, theta1, psi1;                      
203   double psiPlusPhi, psiMinusPhi;                 
204                                                   
205   theta1 = safe_acos( rzz );                      
206                                                   
207 //  if (rzz > 1 || rzz < -1) {                    
208 //    std::cerr << "HepRotation::eulerAngles()    
209 //        << "HepRotation::eulerAngles() finds    
210 //  }                                             
211                                                   
212   double cosTheta = rzz;                          
213   if (cosTheta > 1)  cosTheta = 1;                
214   if (cosTheta < -1) cosTheta = -1;               
215                                                   
216   if (cosTheta == 1) {                            
217     psiPlusPhi = std::atan2 ( rxy - ryx, rxx +    
218     psiMinusPhi = 0;                              
219                                                   
220   } else if (cosTheta >= 0) {                     
221                                                   
222     // In this realm, the atan2 expression for    
223     psiPlusPhi = std::atan2 ( rxy - ryx, rxx +    
224                                                   
225     // psi - phi is potentially more subtle, b    
226     double s1 = -rxy - ryx; // sin (psi-phi) *    
227     double c1 =  rxx - ryy; // cos (psi-phi) *    
228     psiMinusPhi = std::atan2 ( s1, c1 );          
229                                                   
230   } else if (cosTheta > -1) {                     
231                                                   
232     // In this realm, the atan2 expression for    
233     psiMinusPhi = std::atan2 ( -rxy - ryx, rxx    
234                                                   
235    // psi + phi is potentially more subtle, bu    
236     double s1 = rxy - ryx; // sin (psi+phi) *     
237     double c1 = rxx + ryy; // cos (psi+phi) *     
238     psiPlusPhi = std::atan2 ( s1, c1 );           
239                                                   
240   } else { // cosTheta == -1                      
241                                                   
242     psiMinusPhi = std::atan2 ( -rxy - ryx, rxx    
243     psiPlusPhi = 0;                               
244                                                   
245   }                                               
246                                                   
247   psi1 = .5 * (psiPlusPhi + psiMinusPhi);         
248   phi1 = .5 * (psiPlusPhi - psiMinusPhi);         
249                                                   
250   // Now correct by pi if we have managed to g    
251   // or psiMinusPhi that was off by 2 pi:         
252   correctPsiPhi ( rxz, rzx, ryz, rzy, psi1, ph    
253                                                   
254   return  HepEulerAngles( phi1, theta1, psi1 )    
255                                                   
256 } // eulerAngles()                                
257                                                   
258                                                   
259 void HepRotation::setPhi (double phi1) {          
260   set ( phi1, theta(), psi() );                   
261 }                                                 
262                                                   
263 void HepRotation::setTheta (double theta1) {      
264   set ( phi(), theta1, psi() );                   
265 }                                                 
266                                                   
267 void HepRotation::setPsi (double psi1) {          
268   set ( phi(), theta(), psi1 );                   
269 }                                                 
270                                                   
271 }  // namespace CLHEP                             
272                                                   
273