RotationZYX.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: RotationZYX.cxx 22516 2008-03-07 15:14:26Z moneta $
00002 // Authors: W. Brown, M. Fischler, L. Moneta    2005  
00003 
00004  /**********************************************************************
00005   *                                                                    *
00006   * Copyright (c) 2005 , LCG ROOT FNAL MathLib Team                    *
00007   *                                                                    *
00008   *                                                                    *
00009   **********************************************************************/
00010 
00011 // Implementation file for rotation in 3 dimensions, represented by RotationZYX
00012 //
00013 // Created by: Lorenzo Moneta, May 23 2007
00014 //
00015 // Last update: $Id: RotationZYX.cxx 22516 2008-03-07 15:14:26Z moneta $
00016 //
00017 #include "Math/GenVector/RotationZYX.h"
00018 
00019 #include <cmath>
00020 
00021 #include "Math/GenVector/Cartesian3D.h"
00022 #include "Math/GenVector/DisplacementVector3D.h"
00023 #include "Math/GenVector/RotationZYX.h"
00024 #include "Math/GenVector/Rotation3D.h"
00025 #include "Math/GenVector/Quaternion.h"
00026 #include "Math/GenVector/RotationX.h"
00027 #include "Math/GenVector/RotationY.h"
00028 #include "Math/GenVector/RotationZ.h"
00029 
00030 #include "Math/GenVector/AxisAnglefwd.h"
00031 
00032 namespace ROOT {
00033 
00034 namespace Math {
00035 
00036 // ========== Constructors and Assignment =====================
00037 
00038 
00039 
00040 // ========== Operations =====================
00041 
00042 // DisplacementVector3D< Cartesian3D<double> >
00043 // RotationZYX::
00044 // operator() (const DisplacementVector3D< Cartesian3D<double> > & v) const
00045 // {
00046 //   return Rotation3D(*this)(v);
00047 // }
00048 
00049 
00050 RotationZYX RotationZYX::operator * (const Rotation3D  & r) const {
00051    // combine with a Rotation3D
00052    return RotationZYX ( Rotation3D(*this) * r );
00053 }
00054 
00055 RotationZYX RotationZYX::operator * (const AxisAngle   & a) const {
00056    // combine with a AxisAngle
00057    return RotationZYX ( Quaternion(*this) * Quaternion(a) );
00058 }
00059 
00060 RotationZYX RotationZYX::operator * (const EulerAngles   & e) const {
00061    // combine with EulerAngles
00062    return RotationZYX ( Quaternion(*this) * Quaternion(e) );
00063 }
00064 
00065 RotationZYX RotationZYX::operator * (const RotationZYX & e) const {
00066    // combine with a RotationZYX
00067    //return RotationZYX ( Quaternion(*this) * Quaternion(e) );
00068    return RotationZYX ( Rotation3D(*this) * Rotation3D(e) );
00069 }
00070 RotationZYX RotationZYX::operator * (const Quaternion & q) const {
00071    // combination with a Quaternion
00072    return RotationZYX ( Quaternion(*this) * q );
00073 }
00074 
00075 RotationZYX RotationZYX::operator * (const RotationX  & r) const {
00076    // combine with a RotationX
00077    return RotationZYX ( Quaternion(*this) * r );
00078 }
00079 
00080 RotationZYX RotationZYX::operator * (const RotationY  & r) const {
00081    // combine with a RotationY
00082    return RotationZYX ( Quaternion(*this) * r );
00083 }
00084 
00085 RotationZYX RotationZYX::operator * (const RotationZ  & r) const {
00086    // combine with a RotationZ
00087    // TODO -- this can be made much faster because it merely adds
00088    //         the r.Angle() to phi.
00089    Scalar newPhi = fPhi + r.Angle();
00090    if ( newPhi <= -Pi()|| newPhi > Pi() ) {
00091       newPhi = newPhi - std::floor( newPhi/(2*Pi()) +.5 ) * 2*Pi();
00092    }
00093    return RotationZYX ( newPhi, fTheta, fPsi );
00094 }
00095 
00096 RotationZYX operator * ( RotationX const & r, RotationZYX const & e )  {
00097    return RotationZYX(r) * e;  // TODO: improve performance
00098 }
00099 
00100 RotationZYX operator * ( RotationY const & r, RotationZYX const & e )  {
00101    return RotationZYX(r) * e;  // TODO: improve performance
00102 }
00103 
00104 RotationZYX
00105 operator * ( RotationZ const & r, RotationZYX const & e )  {
00106    return RotationZYX(r) * e;  // TODO: improve performance
00107 }
00108 
00109 void RotationZYX::Rectify()
00110 {
00111    // rectify . The angle theta must be defined between [-PI/2,PI.2]
00112    //  same as Euler- Angles, just here Theta is shifted by PI/2 with respect to 
00113    // the theta of the EulerAngles class
00114 
00115    Scalar theta2 = fTheta + M_PI_2;
00116    if ( theta2 < 0 || theta2 > Pi() ) {
00117       Scalar t = theta2 - std::floor( theta2/(2*Pi() ) ) * 2*Pi();
00118       if ( t <= Pi() ) {
00119          theta2 = t;
00120       } else {
00121          theta2 = 2*Pi() - t;
00122          fPhi =  fPhi + Pi();
00123          fPsi =  fPsi + Pi();
00124       }
00125       // ftheta is shifted of PI/2 w.r.t theta2
00126       fTheta = theta2 - M_PI_2; 
00127    }
00128    
00129    if ( fPhi <= -Pi()|| fPhi > Pi() ) {
00130       fPhi = fPhi - std::floor( fPhi/(2*Pi()) +.5 ) * 2*Pi();
00131    }
00132    
00133    if ( fPsi <= -Pi()|| fPsi > Pi() ) {
00134       fPsi = fPsi - std::floor( fPsi/(2*Pi()) +.5 ) * 2*Pi();
00135    }
00136    
00137 } // Rectify()
00138 
00139 void RotationZYX::Invert()
00140 {
00141    // invert this rotation. 
00142    // use Rotation3D. TO Do :have algorithm to invert it directly
00143    Rotation3D r(*this);
00144    //Quaternion r(*this);
00145    r.Invert();
00146    *this = r;
00147 }
00148 
00149 // ========== I/O =====================
00150 
00151 std::ostream & operator<< (std::ostream & os, const RotationZYX & e) {
00152    // TODO - this will need changing for machine-readable issues
00153    //        and even the human readable form may need formatiing improvements
00154    os << "\n{phi(Z angle): " << e.Phi() << "   theta(Y angle): " << e.Theta() 
00155    << "   psi(X angle): " << e.Psi() << "}\n"; 
00156    return os;
00157 }
00158 
00159 
00160 } //namespace Math
00161 } //namespace ROOT

Generated on Tue Jul 5 14:33:07 2011 for ROOT_528-00b_version by  doxygen 1.5.1