ROOT logo
// @(#)root/mathcore:$Id$
// Authors: W. Brown, M. Fischler, L. Moneta    2005  

 /**********************************************************************
  *                                                                    *
  * Copyright (c) 2005 , LCG ROOT MathLib Team                         *
  *                                                                    *
  *                                                                    *
  **********************************************************************/

// Header file for class EulerAngles
//
// Created by: Lorenzo Moneta  at Tue May 10 17:55:10 2005
//
// Last update: Tue May 10 17:55:10 2005
//
#ifndef ROOT_Math_GenVector_EulerAngles 
#define ROOT_Math_GenVector_EulerAngles  1

#include "Math/GenVector/Rotation3D.h"
#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/PositionVector3D.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/3DConversions.h"
#include <algorithm>
#include <cassert>

namespace ROOT {
namespace Math {


//__________________________________________________________________________________________
   /**
      EulerAngles class describing rotation as three angles (Euler Angles).
      The Euler angles definition matches that of Classical Mechanics (Goldstein).
      It is also the same convention defined in 
      <A HREF="http://mathworld.wolfram.com/EulerAngles.html">mathworld</A> 
      and used in Mathematica and CLHEP. Note that the ROOT class TRotation defines 
      a slightly different convention. 
      
      @ingroup GenVector
   */
class EulerAngles {

public:

   typedef double Scalar;

  /**
     Default constructor
  */
   EulerAngles() : fPhi(0.0), fTheta(0.0), fPsi(0.0) { }

   /**
      Constructor from phi, theta and psi
   */
   EulerAngles( Scalar phi, Scalar theta, Scalar psi ) :
      fPhi(phi), fTheta(theta), fPsi(psi)
   {Rectify();} // Added 27 Jan. 06   JMM

   /**
      Construct given a pair of pointers or iterators defining the
      beginning and end of an array of three Scalars, to be treated as
      the angles phi, theta and psi.
   */
   template<class IT>
   EulerAngles(IT begin, IT end) { SetComponents(begin,end); }

   // The compiler-generated copy ctor, copy assignment, and dtor are OK.

   /**
      Re-adjust components place angles in canonical ranges
   */
   void Rectify();


   // ======== Construction and assignement from any other rotation ==================

   /**
      Create from any other supported rotation (see gv_detail::convert )
    */
   template <class OtherRotation> 
   explicit EulerAngles(const OtherRotation & r) {gv_detail::convert(r,*this);}

   /**
      Assign from any other rotation (see gv_detail::convert )
   */
   template <class OtherRotation> 
   EulerAngles &  operator=( OtherRotation const  & r ) { 
      gv_detail::convert(r,*this); 
      return *this;
   }

#ifdef OLD
   explicit EulerAngles(const Rotation3D & r) {gv_detail::convert(r,*this);}

   /**
      Construct from a rotation matrix
   */
   explicit EulerAngles(const Rotation3D & r) {gv_detail::convert(r,*this);}

   /**
      Construct from a rotation represented by a Quaternion
   */
   explicit EulerAngles(const Quaternion & q) {gv_detail::convert(q,*this);}

   /**
      Construct from an AxisAngle
   */
   explicit EulerAngles(const AxisAngle & a ) { gv_detail::convert(a, *this); }

   /**
      Construct from an axial rotation
   */
   explicit EulerAngles( RotationZ const & r ) { gv_detail::convert(r, *this); }
   explicit EulerAngles( RotationY const & r ) { gv_detail::convert(r, *this); }
   explicit EulerAngles( RotationX const & r ) { gv_detail::convert(r, *this); }


   /**
      Assign from an AxisAngle
   */
   EulerAngles &
   operator=( AxisAngle const & a ) { return operator=(EulerAngles(a)); }

   /**
      Assign from a Quaternion
   */
   EulerAngles &
   operator=( Quaternion const  & q ) {return operator=(EulerAngles(q)); }

   /**
      Assign from an axial rotation
   */
   EulerAngles &
   operator=( RotationZ const & r ) { return operator=(EulerAngles(r)); }
   EulerAngles &
   operator=( RotationY const & r ) { return operator=(EulerAngles(r)); }
   EulerAngles &
   operator=( RotationX const & r ) { return operator=(EulerAngles(r)); }

#endif

   // ======== Components ==============

   /**
      Set the three Euler angles given a pair of pointers or iterators
      defining the beginning and end of an array of three Scalars.
   */
   template<class IT>
   void SetComponents(IT begin, IT end) {
      (void)end;
      fPhi   = *begin++;
      fTheta = *begin++;
      fPsi   = *begin++;
      assert(begin == end); 
      Rectify(); // Added 27 Jan. 06   JMM
   }

   /**
      Get the axis and then the angle into data specified by an iterator begin
      and another to the end of the desired data (4 past start).
   */
   template<class IT>
   void GetComponents(IT begin, IT end) const {
      (void)end;
      *begin++ = fPhi;
      *begin++ = fTheta;
      *begin++ = fPsi;
      assert(begin == end); 
   }

   /**
      Get the axis and then the angle into data specified by an iterator begin
   */
   template<class IT>
   void GetComponents(IT begin) const {
      *begin++ = fPhi;
      *begin++ = fTheta;
      *begin   = fPsi;
   }

   /**
      Set the components phi, theta, psi based on three Scalars.
   */
   void SetComponents(Scalar phi, Scalar theta, Scalar psi) {
      fPhi=phi; fTheta=theta; fPsi=psi; 
      Rectify(); // Added 27 Jan. 06   JMM
   }

   /**
      Get the components phi, theta, psi into three Scalars.
   */
   void GetComponents(Scalar & phi, Scalar & theta, Scalar & psi) const {
      phi=fPhi; theta=fTheta; psi=fPsi;
   }

   /**
      Set Phi Euler angle // JMM 30 Jan. 2006
   */
   void SetPhi(Scalar phi) { fPhi=phi; Rectify(); }

   /**
      Return Phi Euler angle
   */
   Scalar Phi() const { return fPhi; }

   /**
      Set Theta Euler angle // JMM 30 Jan. 2006
   */
   void SetTheta(Scalar theta) { fTheta=theta; Rectify(); }

   /**
      Return Theta Euler angle
   */
   Scalar Theta() const { return fTheta; }

   /**
      Set Psi Euler angle // JMM 30 Jan. 2006
   */
   void SetPsi(Scalar psi) { fPsi=psi; Rectify(); }

   /**
      Return Psi Euler angle
   */
   Scalar Psi() const { return fPsi; }

   // =========== operations ==============


   /**
      Rotation operation on a displacement vector in any coordinate system and tag
   */
   template <class CoordSystem, class U>
   DisplacementVector3D<CoordSystem,U>
   operator() (const DisplacementVector3D<CoordSystem,U> & v) const {
      return Rotation3D(*this) ( v );
   }

   /**
      Rotation operation on a position vector in any coordinate system
   */
   template <class CoordSystem, class U>
   PositionVector3D<CoordSystem, U>
   operator() (const PositionVector3D<CoordSystem,U> & v) const {
      DisplacementVector3D< Cartesian3D<double>,U > xyz(v);
      DisplacementVector3D< Cartesian3D<double>,U > rxyz = operator()(xyz);
      return PositionVector3D<CoordSystem,U> ( rxyz );
   }

   /**
      Rotation operation on a Lorentz vector in any 4D coordinate system
   */
   template <class CoordSystem>
   LorentzVector<CoordSystem>
   operator() (const LorentzVector<CoordSystem> & v) const {
      DisplacementVector3D< Cartesian3D<double> > xyz(v.Vect());
      xyz = operator()(xyz);
      LorentzVector< PxPyPzE4D<double> > xyzt (xyz.X(), xyz.Y(), xyz.Z(), v.E());
      return LorentzVector<CoordSystem> ( xyzt );
   }

   /**
      Rotation operation on an arbitrary vector v.
      Preconditions:  v must implement methods x(), y(), and z()
      and the arbitrary vector type must have a constructor taking (x,y,z)
   */
   template <class ForeignVector>
   ForeignVector
   operator() (const  ForeignVector & v) const {
      DisplacementVector3D< Cartesian3D<double> > xyz(v);
      DisplacementVector3D< Cartesian3D<double> > rxyz = operator()(xyz);
      return ForeignVector ( rxyz.X(), rxyz.Y(), rxyz.Z() );
   }

   /**
      Overload operator * for rotation on a vector
   */
   template <class AVector>
   inline
   AVector operator* (const AVector & v) const
   {
      return operator()(v);
   }

   /**
      Invert a rotation in place
   */
   // theta stays the same and negative rotation in Theta is done via a rotation 
   // of + PI in phi and Psi 
   void Invert() {
      Scalar tmp = -fPhi; 
      fPhi = -fPsi + Pi(); 
      fPsi=tmp + Pi();
   }

   /**
      Return inverse of a rotation
   */
   EulerAngles Inverse() const { return EulerAngles(-fPsi + Pi(), fTheta, -fPhi + Pi()); }

   // ========= Multi-Rotation Operations ===============

   /**
      Multiply (combine) two rotations
   */
   EulerAngles operator * (const Rotation3D  & r) const;
   EulerAngles operator * (const AxisAngle   & a) const;
   EulerAngles operator * (const EulerAngles & e) const;
   EulerAngles operator * (const Quaternion  & q) const;
   EulerAngles operator * (const RotationX  & rx) const;
   EulerAngles operator * (const RotationY  & ry) const;
   EulerAngles operator * (const RotationZ  & rz) const;

   /**
      Post-Multiply (on right) by another rotation :  T = T*R
   */
   template <class R>
   EulerAngles & operator *= (const R & r) { return *this = (*this)*r; }

   /**
      Distance between two rotations
   */
   template <class R>
   Scalar Distance ( const R & r ) const {return gv_detail::dist(*this,r);}

   /**
      Equality/inequality operators
   */
   bool operator == (const EulerAngles & rhs) const {
      if( fPhi   != rhs.fPhi   ) return false;
      if( fTheta != rhs.fTheta ) return false;
      if( fPsi   != rhs.fPsi   ) return false;
      return true;
   }
   bool operator != (const EulerAngles & rhs) const {
      return ! operator==(rhs);
   }

private:

   double fPhi;     // Z rotation angle (first)  defined in [-PI,PI]
   double fTheta;   // X rotation angle (second) defined only [0,PI]
   double fPsi;     // Z rotation angle (third)  defined in [-PI,PI]

   static double Pi() { return M_PI; }

};  // EulerAngles

/**
   Distance between two rotations
 */
template <class R>
inline
typename EulerAngles::Scalar
Distance ( const EulerAngles& r1, const R & r2) {return gv_detail::dist(r1,r2);}

/**
   Multiplication of an axial rotation by an AxisAngle
 */
EulerAngles operator* (RotationX const & r1, EulerAngles const & r2);
EulerAngles operator* (RotationY const & r1, EulerAngles const & r2);
EulerAngles operator* (RotationZ const & r1, EulerAngles const & r2);

/**
   Stream Output and Input
 */
  // TODO - I/O should be put in the manipulator form 

std::ostream & operator<< (std::ostream & os, const EulerAngles & e);

} // namespace Math
} // namespace ROOT


#endif /* ROOT_Math_GenVector_EulerAngles  */
 EulerAngles.h:1
 EulerAngles.h:2
 EulerAngles.h:3
 EulerAngles.h:4
 EulerAngles.h:5
 EulerAngles.h:6
 EulerAngles.h:7
 EulerAngles.h:8
 EulerAngles.h:9
 EulerAngles.h:10
 EulerAngles.h:11
 EulerAngles.h:12
 EulerAngles.h:13
 EulerAngles.h:14
 EulerAngles.h:15
 EulerAngles.h:16
 EulerAngles.h:17
 EulerAngles.h:18
 EulerAngles.h:19
 EulerAngles.h:20
 EulerAngles.h:21
 EulerAngles.h:22
 EulerAngles.h:23
 EulerAngles.h:24
 EulerAngles.h:25
 EulerAngles.h:26
 EulerAngles.h:27
 EulerAngles.h:28
 EulerAngles.h:29
 EulerAngles.h:30
 EulerAngles.h:31
 EulerAngles.h:32
 EulerAngles.h:33
 EulerAngles.h:34
 EulerAngles.h:35
 EulerAngles.h:36
 EulerAngles.h:37
 EulerAngles.h:38
 EulerAngles.h:39
 EulerAngles.h:40
 EulerAngles.h:41
 EulerAngles.h:42
 EulerAngles.h:43
 EulerAngles.h:44
 EulerAngles.h:45
 EulerAngles.h:46
 EulerAngles.h:47
 EulerAngles.h:48
 EulerAngles.h:49
 EulerAngles.h:50
 EulerAngles.h:51
 EulerAngles.h:52
 EulerAngles.h:53
 EulerAngles.h:54
 EulerAngles.h:55
 EulerAngles.h:56
 EulerAngles.h:57
 EulerAngles.h:58
 EulerAngles.h:59
 EulerAngles.h:60
 EulerAngles.h:61
 EulerAngles.h:62
 EulerAngles.h:63
 EulerAngles.h:64
 EulerAngles.h:65
 EulerAngles.h:66
 EulerAngles.h:67
 EulerAngles.h:68
 EulerAngles.h:69
 EulerAngles.h:70
 EulerAngles.h:71
 EulerAngles.h:72
 EulerAngles.h:73
 EulerAngles.h:74
 EulerAngles.h:75
 EulerAngles.h:76
 EulerAngles.h:77
 EulerAngles.h:78
 EulerAngles.h:79
 EulerAngles.h:80
 EulerAngles.h:81
 EulerAngles.h:82
 EulerAngles.h:83
 EulerAngles.h:84
 EulerAngles.h:85
 EulerAngles.h:86
 EulerAngles.h:87
 EulerAngles.h:88
 EulerAngles.h:89
 EulerAngles.h:90
 EulerAngles.h:91
 EulerAngles.h:92
 EulerAngles.h:93
 EulerAngles.h:94
 EulerAngles.h:95
 EulerAngles.h:96
 EulerAngles.h:97
 EulerAngles.h:98
 EulerAngles.h:99
 EulerAngles.h:100
 EulerAngles.h:101
 EulerAngles.h:102
 EulerAngles.h:103
 EulerAngles.h:104
 EulerAngles.h:105
 EulerAngles.h:106
 EulerAngles.h:107
 EulerAngles.h:108
 EulerAngles.h:109
 EulerAngles.h:110
 EulerAngles.h:111
 EulerAngles.h:112
 EulerAngles.h:113
 EulerAngles.h:114
 EulerAngles.h:115
 EulerAngles.h:116
 EulerAngles.h:117
 EulerAngles.h:118
 EulerAngles.h:119
 EulerAngles.h:120
 EulerAngles.h:121
 EulerAngles.h:122
 EulerAngles.h:123
 EulerAngles.h:124
 EulerAngles.h:125
 EulerAngles.h:126
 EulerAngles.h:127
 EulerAngles.h:128
 EulerAngles.h:129
 EulerAngles.h:130
 EulerAngles.h:131
 EulerAngles.h:132
 EulerAngles.h:133
 EulerAngles.h:134
 EulerAngles.h:135
 EulerAngles.h:136
 EulerAngles.h:137
 EulerAngles.h:138
 EulerAngles.h:139
 EulerAngles.h:140
 EulerAngles.h:141
 EulerAngles.h:142
 EulerAngles.h:143
 EulerAngles.h:144
 EulerAngles.h:145
 EulerAngles.h:146
 EulerAngles.h:147
 EulerAngles.h:148
 EulerAngles.h:149
 EulerAngles.h:150
 EulerAngles.h:151
 EulerAngles.h:152
 EulerAngles.h:153
 EulerAngles.h:154
 EulerAngles.h:155
 EulerAngles.h:156
 EulerAngles.h:157
 EulerAngles.h:158
 EulerAngles.h:159
 EulerAngles.h:160
 EulerAngles.h:161
 EulerAngles.h:162
 EulerAngles.h:163
 EulerAngles.h:164
 EulerAngles.h:165
 EulerAngles.h:166
 EulerAngles.h:167
 EulerAngles.h:168
 EulerAngles.h:169
 EulerAngles.h:170
 EulerAngles.h:171
 EulerAngles.h:172
 EulerAngles.h:173
 EulerAngles.h:174
 EulerAngles.h:175
 EulerAngles.h:176
 EulerAngles.h:177
 EulerAngles.h:178
 EulerAngles.h:179
 EulerAngles.h:180
 EulerAngles.h:181
 EulerAngles.h:182
 EulerAngles.h:183
 EulerAngles.h:184
 EulerAngles.h:185
 EulerAngles.h:186
 EulerAngles.h:187
 EulerAngles.h:188
 EulerAngles.h:189
 EulerAngles.h:190
 EulerAngles.h:191
 EulerAngles.h:192
 EulerAngles.h:193
 EulerAngles.h:194
 EulerAngles.h:195
 EulerAngles.h:196
 EulerAngles.h:197
 EulerAngles.h:198
 EulerAngles.h:199
 EulerAngles.h:200
 EulerAngles.h:201
 EulerAngles.h:202
 EulerAngles.h:203
 EulerAngles.h:204
 EulerAngles.h:205
 EulerAngles.h:206
 EulerAngles.h:207
 EulerAngles.h:208
 EulerAngles.h:209
 EulerAngles.h:210
 EulerAngles.h:211
 EulerAngles.h:212
 EulerAngles.h:213
 EulerAngles.h:214
 EulerAngles.h:215
 EulerAngles.h:216
 EulerAngles.h:217
 EulerAngles.h:218
 EulerAngles.h:219
 EulerAngles.h:220
 EulerAngles.h:221
 EulerAngles.h:222
 EulerAngles.h:223
 EulerAngles.h:224
 EulerAngles.h:225
 EulerAngles.h:226
 EulerAngles.h:227
 EulerAngles.h:228
 EulerAngles.h:229
 EulerAngles.h:230
 EulerAngles.h:231
 EulerAngles.h:232
 EulerAngles.h:233
 EulerAngles.h:234
 EulerAngles.h:235
 EulerAngles.h:236
 EulerAngles.h:237
 EulerAngles.h:238
 EulerAngles.h:239
 EulerAngles.h:240
 EulerAngles.h:241
 EulerAngles.h:242
 EulerAngles.h:243
 EulerAngles.h:244
 EulerAngles.h:245
 EulerAngles.h:246
 EulerAngles.h:247
 EulerAngles.h:248
 EulerAngles.h:249
 EulerAngles.h:250
 EulerAngles.h:251
 EulerAngles.h:252
 EulerAngles.h:253
 EulerAngles.h:254
 EulerAngles.h:255
 EulerAngles.h:256
 EulerAngles.h:257
 EulerAngles.h:258
 EulerAngles.h:259
 EulerAngles.h:260
 EulerAngles.h:261
 EulerAngles.h:262
 EulerAngles.h:263
 EulerAngles.h:264
 EulerAngles.h:265
 EulerAngles.h:266
 EulerAngles.h:267
 EulerAngles.h:268
 EulerAngles.h:269
 EulerAngles.h:270
 EulerAngles.h:271
 EulerAngles.h:272
 EulerAngles.h:273
 EulerAngles.h:274
 EulerAngles.h:275
 EulerAngles.h:276
 EulerAngles.h:277
 EulerAngles.h:278
 EulerAngles.h:279
 EulerAngles.h:280
 EulerAngles.h:281
 EulerAngles.h:282
 EulerAngles.h:283
 EulerAngles.h:284
 EulerAngles.h:285
 EulerAngles.h:286
 EulerAngles.h:287
 EulerAngles.h:288
 EulerAngles.h:289
 EulerAngles.h:290
 EulerAngles.h:291
 EulerAngles.h:292
 EulerAngles.h:293
 EulerAngles.h:294
 EulerAngles.h:295
 EulerAngles.h:296
 EulerAngles.h:297
 EulerAngles.h:298
 EulerAngles.h:299
 EulerAngles.h:300
 EulerAngles.h:301
 EulerAngles.h:302
 EulerAngles.h:303
 EulerAngles.h:304
 EulerAngles.h:305
 EulerAngles.h:306
 EulerAngles.h:307
 EulerAngles.h:308
 EulerAngles.h:309
 EulerAngles.h:310
 EulerAngles.h:311
 EulerAngles.h:312
 EulerAngles.h:313
 EulerAngles.h:314
 EulerAngles.h:315
 EulerAngles.h:316
 EulerAngles.h:317
 EulerAngles.h:318
 EulerAngles.h:319
 EulerAngles.h:320
 EulerAngles.h:321
 EulerAngles.h:322
 EulerAngles.h:323
 EulerAngles.h:324
 EulerAngles.h:325
 EulerAngles.h:326
 EulerAngles.h:327
 EulerAngles.h:328
 EulerAngles.h:329
 EulerAngles.h:330
 EulerAngles.h:331
 EulerAngles.h:332
 EulerAngles.h:333
 EulerAngles.h:334
 EulerAngles.h:335
 EulerAngles.h:336
 EulerAngles.h:337
 EulerAngles.h:338
 EulerAngles.h:339
 EulerAngles.h:340
 EulerAngles.h:341
 EulerAngles.h:342
 EulerAngles.h:343
 EulerAngles.h:344
 EulerAngles.h:345
 EulerAngles.h:346
 EulerAngles.h:347
 EulerAngles.h:348
 EulerAngles.h:349
 EulerAngles.h:350
 EulerAngles.h:351
 EulerAngles.h:352
 EulerAngles.h:353
 EulerAngles.h:354
 EulerAngles.h:355
 EulerAngles.h:356
 EulerAngles.h:357
 EulerAngles.h:358
 EulerAngles.h:359
 EulerAngles.h:360
 EulerAngles.h:361
 EulerAngles.h:362
 EulerAngles.h:363
 EulerAngles.h:364
 EulerAngles.h:365
 EulerAngles.h:366
 EulerAngles.h:367
 EulerAngles.h:368
 EulerAngles.h:369
 EulerAngles.h:370
 EulerAngles.h:371
 EulerAngles.h:372
 EulerAngles.h:373
 EulerAngles.h:374
 EulerAngles.h:375
 EulerAngles.h:376