15 #pragma implementation 
   18 #include "CLHEP/Vector/Rotation.h" 
   19 #include "CLHEP/Vector/EulerAngles.h" 
   20 #include "CLHEP/Units/PhysicalConstants.h" 
   27   if (std::abs(x) <= 1.0) 
return std::acos(x);
 
   35 HepRotation & HepRotation::set(
double phi1, 
double theta1, 
double psi1) {
 
   37   register double sinPhi   = std::sin( phi1   ), cosPhi   = std::cos( phi1   );
 
   38   register double sinTheta = std::sin( theta1 ), cosTheta = std::cos( theta1 );
 
   39   register double sinPsi   = std::sin( psi1   ), cosPsi   = std::cos( psi1   );
 
   41   rxx =   cosPsi * cosPhi - cosTheta * sinPhi * sinPsi;
 
   42   rxy =   cosPsi * sinPhi + cosTheta * cosPhi * sinPsi;
 
   43   rxz =   sinPsi * sinTheta;
 
   45   ryx = - sinPsi * cosPhi - cosTheta * sinPhi * cosPsi;
 
   46   ryy = - sinPsi * sinPhi + cosTheta * cosPhi * cosPsi;
 
   47   ryz =   cosPsi * sinTheta;
 
   49   rzx =   sinTheta * sinPhi;
 
   50   rzy = - sinTheta * cosPhi;
 
   57 HepRotation::HepRotation( 
double phi1, 
double theta1, 
double psi1 ) 
 
   59   set (phi1, theta1, psi1);
 
   61 HepRotation & HepRotation::set( 
const HepEulerAngles & e ) {
 
   62   return set(e.phi(), e.theta(), e.psi());
 
   64 HepRotation::HepRotation ( 
const HepEulerAngles & e ) 
 
   66   set(e.phi(), e.theta(), e.psi());
 
   70 double HepRotation::phi  ()
 const {
 
   72   double s2 =  1.0 - rzz*rzz;
 
   74     std::cerr << 
"HepRotation::phi() - " 
   75         << 
"HepRotation::phi() finds | rzz | > 1 " << std::endl;
 
   78   const double sinTheta = std::sqrt( s2 );
 
   82     HepEulerAngles ea = eulerAngles();
 
   86   const double cscTheta = 1/sinTheta;
 
   87   double cosabsphi =  - rzy * cscTheta;
 
   88   if ( std::fabs(cosabsphi) > 1 ) {     
 
   89     std::cerr << 
"HepRotation::phi() - " 
   90       << 
"HepRotation::phi() finds | cos phi | > 1 " << std::endl;
 
   93   const double absPhi = std::acos ( cosabsphi );
 
  104 double HepRotation::theta()
 const {
 
  110 double HepRotation::psi  ()
 const {
 
  113   if ( std::fabs(rzz) > 1 ) {   
 
  114     std::cerr << 
"HepRotation::psi() - " 
  115       << 
"HepRotation::psi() finds | rzz | > 1" << std::endl;
 
  118     sinTheta = std::sqrt( 1.0 - rzz*rzz );
 
  121   if (sinTheta < .01) { 
 
  123     HepEulerAngles ea = eulerAngles();
 
  127   const double cscTheta = 1/sinTheta;
 
  128   double cosabspsi =  ryz * cscTheta;
 
  129   if ( std::fabs(cosabspsi) > 1 ) {     
 
  130     std::cerr << 
"HepRotation::psi() - " 
  131       << 
"HepRotation::psi() finds | cos psi | > 1" << std::endl;
 
  134   const double absPsi = std::acos ( cosabspsi );
 
  137   } 
else if (rxz < 0) {
 
  163                      double& psi1, 
double& phi1 ) {
 
  168   w[0] = rxz; w[1] = rzx; w[2] = ryz; w[3] = -rzy;
 
  171   double maxw = std::abs(w[0]); 
 
  173   for (
int i = 1; i < 4; ++i) {
 
  174     if (std::abs(w[i]) > maxw) {
 
  175       maxw = std::abs(w[i]);
 
  183       if (w[0] > 0 && psi1 < 0)           
correctByPi ( psi1, phi1 );
 
  184       if (w[0] < 0 && psi1 > 0)           
correctByPi ( psi1, phi1 );
 
  187       if (w[1] > 0 && phi1 < 0)           
correctByPi ( psi1, phi1 );
 
  188       if (w[1] < 0 && phi1 > 0)           
correctByPi ( psi1, phi1 );
 
  191       if (w[2] > 0 && std::abs(psi1) > CLHEP::halfpi) 
correctByPi ( psi1, phi1 );    
 
  192       if (w[2] < 0 && std::abs(psi1) < CLHEP::halfpi) 
correctByPi ( psi1, phi1 );    
 
  195       if (w[3] > 0 && std::abs(phi1) > CLHEP::halfpi) 
correctByPi ( psi1, phi1 );    
 
  196       if (w[3] < 0 && std::abs(phi1) < CLHEP::halfpi) 
correctByPi ( psi1, phi1 );    
 
  201 HepEulerAngles HepRotation::eulerAngles()
 const {
 
  205   double phi1, theta1, psi1;
 
  206   double psiPlusPhi, psiMinusPhi;
 
  215   double cosTheta = rzz;
 
  216   if (cosTheta > 1)  cosTheta = 1;
 
  217   if (cosTheta < -1) cosTheta = -1;
 
  220     psiPlusPhi = std::atan2 ( rxy - ryx, rxx + ryy );
 
  223   } 
else if (cosTheta >= 0) {
 
  226     psiPlusPhi = std::atan2 ( rxy - ryx, rxx + ryy );
 
  229     double s1 = -rxy - ryx; 
 
  230     double c1 =  rxx - ryy; 
 
  231     psiMinusPhi = std::atan2 ( s1, c1 );
 
  233   } 
else if (cosTheta > -1) {
 
  236     psiMinusPhi = std::atan2 ( -rxy - ryx, rxx - ryy );
 
  239     double s1 = rxy - ryx; 
 
  240     double c1 = rxx + ryy; 
 
  241     psiPlusPhi = std::atan2 ( s1, c1 );
 
  245     psiMinusPhi = std::atan2 ( -rxy - ryx, rxx - ryy );
 
  250   psi1 = .5 * (psiPlusPhi + psiMinusPhi); 
 
  251   phi1 = .5 * (psiPlusPhi - psiMinusPhi); 
 
  257   return  HepEulerAngles( phi1, theta1, psi1 );
 
  262 void HepRotation::setPhi (
double phi1) {
 
  263   set ( phi1, theta(), psi() );
 
  266 void HepRotation::setTheta (
double theta1) {
 
  267   set ( phi(), theta1, psi() );
 
  270 void HepRotation::setPsi (
double psi1) {
 
  271   set ( phi(), theta(), psi1 );
 
static void correctByPi(double &psi1, double &phi1)
 
static void correctPsiPhi(double rxz, double rzx, double ryz, double rzy, double &psi1, double &phi1)
 
static double safe_acos(double x)