ROOT logo
// @(#)root/mathcore:$Id: RotationZ.h 22516 2008-03-07 15:14:26Z moneta $
// Authors: W. Brown, M. Fischler, L. Moneta    2005  

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

// Header file for class RotationZ representing a rotation about the Z axis
//
// Created by: Mark Fischler Mon July 18  2005
//
// Last update: $Id: RotationZ.h 22516 2008-03-07 15:14:26Z moneta $
//
#ifndef ROOT_Math_GenVector_RotationZ 
#define ROOT_Math_GenVector_RotationZ  1


#include "Math/GenVector/Cartesian3D.h"
#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/PositionVector3D.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/3DDistances.h"

#include "Math/GenVector/RotationZfwd.h"

#include <cmath>

namespace ROOT {
namespace Math {


//__________________________________________________________________________________________
   /**
      Rotation class representing a 3D rotation about the Z axis by the angle of rotation.  
      For efficiency reason, in addition to the the angle, the sine and cosine of the angle are held 
      
      @ingroup GenVector
   */

class RotationZ {

public:

   typedef double Scalar;


   // ========== Constructors and Assignment =====================

   /**
      Default constructor (identity rotation)
   */
   RotationZ() : fAngle(0), fSin(0), fCos(1) { }

   /**
      Construct from an angle
   */
   explicit RotationZ( Scalar angle ) :   fAngle(angle),
                                          fSin(std::sin(angle)),
                                          fCos(std::cos(angle)) 
   {
      Rectify(); 
   }

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

   /**
      Rectify makes sure the angle is in (-pi,pi]
   */
   void Rectify()  {
      if ( std::fabs(fAngle) >= M_PI ) {
         double x = fAngle / (2.0 * M_PI);
         fAngle =  (2.0 * M_PI) * ( x + std::floor(.5-x) );
         fSin = std::sin(fAngle);
         fCos = std::cos(fAngle);
      }
   }

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

   /**
      Set given the angle.
   */
   void SetAngle (Scalar angle) {
      fSin=std::sin(angle);
      fCos=std::cos(angle);
      fAngle= angle; 
      Rectify();     
   }
   void SetComponents (Scalar angle) { SetAngle(angle); }

   /**
      Get the angle
   */
   void GetAngle ( Scalar & angle ) const { angle = atan2 (fSin,fCos); }
   void GetComponents ( Scalar & angle ) const { GetAngle(angle); }

   /**
      Angle of rotation
   */
   Scalar Angle () const { return atan2 (fSin,fCos); }

   /**
      Sine or Cosine of the rotation angle
   */
   Scalar SinAngle () const { return fSin; }
   Scalar CosAngle () const { return fCos; }

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

//   /**
//      Rotation operation on a cartesian vector
//    */
//   typedef  DisplacementVector3D< Cartesian3D<double> > XYZVector; 
//   XYZVector operator() (const XYZVector & v) const {
//     return XYZVector
//       ( fCos*v.x()-fSin*v.y(), fCos*v.y()+fSin*v.x(), v.z() );
//   }

   /**
      Rotation operation on a displacement vector in any coordinate system
   */
   template <class CoordSystem, class U>
   DisplacementVector3D<CoordSystem,U>
   operator() (const DisplacementVector3D<CoordSystem,U> & v) const {
      DisplacementVector3D< Cartesian3D<double>,U > xyz;
      xyz.SetXYZ( fCos*v.x()-fSin*v.y(), fCos*v.y()+fSin*v.x(), v.z()  );
      return DisplacementVector3D<CoordSystem,U>(xyz);
   }

   /**
      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
   */
   void Invert() { fAngle = -fAngle; fSin = -fSin; }

   /**
      Return inverse of  a rotation
   */
   RotationZ Inverse() const { RotationZ t(*this); t.Invert(); return t; }

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

   /**
      Multiply (combine) two rotations
   */
   RotationZ operator * (const RotationZ & r) const {
      RotationZ ans;
      double x   = (fAngle + r.fAngle) / (2.0 * M_PI);
      ans.fAngle = (2.0 * M_PI) * ( x + std::floor(.5-x) );
      ans.fSin   = fSin*r.fCos + fCos*r.fSin;
      ans.fCos   = fCos*r.fCos - fSin*r.fSin;
      return ans;
   }

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

   /**
      Equality/inequality operators
   */
   bool operator == (const RotationZ & rhs) const {
      if( fAngle != rhs.fAngle )  return false;
      return true;
   }
   bool operator != (const RotationZ & rhs) const {
      return ! operator==(rhs);
   }

private:

   Scalar fAngle;   // rotation angle 
   Scalar fSin;     // sine of the rotation angle 
   Scalar fCos;     // cosine of the rotaiton angle 

};  // RotationZ

// ============ Class RotationZ ends here ============

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

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

inline
std::ostream & operator<< (std::ostream & os, const RotationZ & r) {
  os << " RotationZ(" << r.Angle() << ") ";
  return os;
} 
  

}  // namespace Math
}  // namespace ROOT

#endif // ROOT_Math_GenVector_RotationZ 
 RotationZ.h:1
 RotationZ.h:2
 RotationZ.h:3
 RotationZ.h:4
 RotationZ.h:5
 RotationZ.h:6
 RotationZ.h:7
 RotationZ.h:8
 RotationZ.h:9
 RotationZ.h:10
 RotationZ.h:11
 RotationZ.h:12
 RotationZ.h:13
 RotationZ.h:14
 RotationZ.h:15
 RotationZ.h:16
 RotationZ.h:17
 RotationZ.h:18
 RotationZ.h:19
 RotationZ.h:20
 RotationZ.h:21
 RotationZ.h:22
 RotationZ.h:23
 RotationZ.h:24
 RotationZ.h:25
 RotationZ.h:26
 RotationZ.h:27
 RotationZ.h:28
 RotationZ.h:29
 RotationZ.h:30
 RotationZ.h:31
 RotationZ.h:32
 RotationZ.h:33
 RotationZ.h:34
 RotationZ.h:35
 RotationZ.h:36
 RotationZ.h:37
 RotationZ.h:38
 RotationZ.h:39
 RotationZ.h:40
 RotationZ.h:41
 RotationZ.h:42
 RotationZ.h:43
 RotationZ.h:44
 RotationZ.h:45
 RotationZ.h:46
 RotationZ.h:47
 RotationZ.h:48
 RotationZ.h:49
 RotationZ.h:50
 RotationZ.h:51
 RotationZ.h:52
 RotationZ.h:53
 RotationZ.h:54
 RotationZ.h:55
 RotationZ.h:56
 RotationZ.h:57
 RotationZ.h:58
 RotationZ.h:59
 RotationZ.h:60
 RotationZ.h:61
 RotationZ.h:62
 RotationZ.h:63
 RotationZ.h:64
 RotationZ.h:65
 RotationZ.h:66
 RotationZ.h:67
 RotationZ.h:68
 RotationZ.h:69
 RotationZ.h:70
 RotationZ.h:71
 RotationZ.h:72
 RotationZ.h:73
 RotationZ.h:74
 RotationZ.h:75
 RotationZ.h:76
 RotationZ.h:77
 RotationZ.h:78
 RotationZ.h:79
 RotationZ.h:80
 RotationZ.h:81
 RotationZ.h:82
 RotationZ.h:83
 RotationZ.h:84
 RotationZ.h:85
 RotationZ.h:86
 RotationZ.h:87
 RotationZ.h:88
 RotationZ.h:89
 RotationZ.h:90
 RotationZ.h:91
 RotationZ.h:92
 RotationZ.h:93
 RotationZ.h:94
 RotationZ.h:95
 RotationZ.h:96
 RotationZ.h:97
 RotationZ.h:98
 RotationZ.h:99
 RotationZ.h:100
 RotationZ.h:101
 RotationZ.h:102
 RotationZ.h:103
 RotationZ.h:104
 RotationZ.h:105
 RotationZ.h:106
 RotationZ.h:107
 RotationZ.h:108
 RotationZ.h:109
 RotationZ.h:110
 RotationZ.h:111
 RotationZ.h:112
 RotationZ.h:113
 RotationZ.h:114
 RotationZ.h:115
 RotationZ.h:116
 RotationZ.h:117
 RotationZ.h:118
 RotationZ.h:119
 RotationZ.h:120
 RotationZ.h:121
 RotationZ.h:122
 RotationZ.h:123
 RotationZ.h:124
 RotationZ.h:125
 RotationZ.h:126
 RotationZ.h:127
 RotationZ.h:128
 RotationZ.h:129
 RotationZ.h:130
 RotationZ.h:131
 RotationZ.h:132
 RotationZ.h:133
 RotationZ.h:134
 RotationZ.h:135
 RotationZ.h:136
 RotationZ.h:137
 RotationZ.h:138
 RotationZ.h:139
 RotationZ.h:140
 RotationZ.h:141
 RotationZ.h:142
 RotationZ.h:143
 RotationZ.h:144
 RotationZ.h:145
 RotationZ.h:146
 RotationZ.h:147
 RotationZ.h:148
 RotationZ.h:149
 RotationZ.h:150
 RotationZ.h:151
 RotationZ.h:152
 RotationZ.h:153
 RotationZ.h:154
 RotationZ.h:155
 RotationZ.h:156
 RotationZ.h:157
 RotationZ.h:158
 RotationZ.h:159
 RotationZ.h:160
 RotationZ.h:161
 RotationZ.h:162
 RotationZ.h:163
 RotationZ.h:164
 RotationZ.h:165
 RotationZ.h:166
 RotationZ.h:167
 RotationZ.h:168
 RotationZ.h:169
 RotationZ.h:170
 RotationZ.h:171
 RotationZ.h:172
 RotationZ.h:173
 RotationZ.h:174
 RotationZ.h:175
 RotationZ.h:176
 RotationZ.h:177
 RotationZ.h:178
 RotationZ.h:179
 RotationZ.h:180
 RotationZ.h:181
 RotationZ.h:182
 RotationZ.h:183
 RotationZ.h:184
 RotationZ.h:185
 RotationZ.h:186
 RotationZ.h:187
 RotationZ.h:188
 RotationZ.h:189
 RotationZ.h:190
 RotationZ.h:191
 RotationZ.h:192
 RotationZ.h:193
 RotationZ.h:194
 RotationZ.h:195
 RotationZ.h:196
 RotationZ.h:197
 RotationZ.h:198
 RotationZ.h:199
 RotationZ.h:200
 RotationZ.h:201
 RotationZ.h:202
 RotationZ.h:203
 RotationZ.h:204
 RotationZ.h:205
 RotationZ.h:206
 RotationZ.h:207
 RotationZ.h:208
 RotationZ.h:209
 RotationZ.h:210
 RotationZ.h:211
 RotationZ.h:212
 RotationZ.h:213
 RotationZ.h:214
 RotationZ.h:215
 RotationZ.h:216
 RotationZ.h:217
 RotationZ.h:218
 RotationZ.h:219
 RotationZ.h:220
 RotationZ.h:221
 RotationZ.h:222
 RotationZ.h:223
 RotationZ.h:224
 RotationZ.h:225
 RotationZ.h:226
 RotationZ.h:227
 RotationZ.h:228
 RotationZ.h:229
 RotationZ.h:230
 RotationZ.h:231
 RotationZ.h:232
 RotationZ.h:233
 RotationZ.h:234
 RotationZ.h:235
 RotationZ.h:236
 RotationZ.h:237
 RotationZ.h:238
 RotationZ.h:239
 RotationZ.h:240
 RotationZ.h:241
 RotationZ.h:242
 RotationZ.h:243
 RotationZ.h:244
 RotationZ.h:245
 RotationZ.h:246
 RotationZ.h:247
 RotationZ.h:248
 RotationZ.h:249
 RotationZ.h:250
 RotationZ.h:251
 RotationZ.h:252