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

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

// Header file for class Cartesian3D
//
// Created by: Lorenzo Moneta  at Mon May 30 11:16:56 2005
// Major revamp:  M. FIschler  at Wed Jun  8 2005
//
// Last update: $ID: $
//
#ifndef ROOT_Math_GenVector_Cartesian3D
#define ROOT_Math_GenVector_Cartesian3D  1

#ifndef ROOT_Math_GenVector_Polar3Dfwd
#include "Math/GenVector/Polar3Dfwd.h"
#endif

#ifndef ROOT_Math_Math
#include "Math/Math.h"
#endif

#include <limits>


#ifndef ROOT_Math_GenVector_eta
#include "Math/GenVector/eta.h"
#endif


namespace ROOT {

namespace Math {

//__________________________________________________________________________________________
  /**
      Class describing a 3D cartesian coordinate system
      (x, y, z coordinates)

      @ingroup GenVector
  */

template <class T = double>
class Cartesian3D {

public :

   typedef T Scalar;

   /**
      Default constructor  with x=y=z=0
   */
   Cartesian3D() : fX(0.0), fY(0.0), fZ(0.0) {  }

   /**
      Constructor from x,y,z coordinates
   */
   Cartesian3D(Scalar xx, Scalar yy, Scalar zz) : fX(xx), fY(yy), fZ(zz) {  }

   /**
      Construct from any Vector or coordinate system implementing
      X(), Y() and Z()
   */
   template <class CoordSystem>
   explicit Cartesian3D(const CoordSystem & v)
      : fX(v.X()), fY(v.Y()), fZ(v.Z()) {  }

   // for g++  3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
   // re-implement them ( there is no no need to have them with g++4)
   /**
      copy constructor
    */
   Cartesian3D(const Cartesian3D & v) :
      fX(v.X()), fY(v.Y()), fZ(v.Z()) {  }

   /**
      assignment operator
    */
   Cartesian3D & operator= (const Cartesian3D & v) {
      fX = v.x();
      fY = v.y();
      fZ = v.z();
      return *this;
   }


   /**
      Set internal data based on an array of 3 Scalar numbers
   */
   void SetCoordinates( const Scalar src[] ) { fX=src[0]; fY=src[1]; fZ=src[2]; }

   /**
      get internal data into an array of 3 Scalar numbers
   */
   void GetCoordinates( Scalar dest[] ) const
   { dest[0] = fX; dest[1] = fY; dest[2] = fZ; }

   /**
      Set internal data based on 3 Scalar numbers
   */
   void SetCoordinates(Scalar  xx, Scalar  yy, Scalar  zz) { fX=xx; fY=yy; fZ=zz; }

   /**
      get internal data into 3 Scalar numbers
   */
   void GetCoordinates(Scalar& xx, Scalar& yy, Scalar& zz) const {xx=fX; yy=fY; zz=fZ;}

   Scalar X()     const { return fX;}
   Scalar Y()     const { return fY;}
   Scalar Z()     const { return fZ;}
   Scalar Mag2()  const { return fX*fX + fY*fY + fZ*fZ;}
   Scalar Perp2() const { return fX*fX + fY*fY ;}
   Scalar Rho()   const { return std::sqrt( Perp2());}
   Scalar R()     const { return std::sqrt( Mag2());}
   Scalar Theta() const { return (fX==0 && fY==0 && fZ==0) ?
                             0 : atan2(Rho(),Z());}
   Scalar Phi()   const { return (fX==0 && fY==0) ? 0 : atan2(fY,fX);}

   // pseudorapidity
   Scalar Eta() const {
      return Impl::Eta_FromRhoZ ( Rho(),fZ);
   }

   /**
       set the x coordinate value keeping y and z constant
   */
   void SetX(Scalar xx) { fX = xx; }

   /**
       set the y coordinate value keeping x and z constant
   */
   void SetY(Scalar yy) { fY = yy; }

   /**
       set the z coordinate value keeping x and y constant
   */
   void SetZ(Scalar zz) { fZ = zz; }

   /**
       set all values using cartesian coordinates
   */
   void SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
      fX=xx;
      fY=yy;
      fZ=zz;
   }

   /**
      scale the vector by a scalar quantity a
   */
   void Scale(Scalar a) { fX *= a; fY *= a;  fZ *= a; }

   /**
      negate the vector
   */
   void Negate() { fX = -fX; fY = -fY;  fZ = -fZ; }

   /**
      Assignment from any class implementing x(),y() and z()
      (can assign from any coordinate system)
   */
   template <class CoordSystem>
   Cartesian3D & operator = (const CoordSystem & v) {
      fX = v.x();
      fY = v.y();
      fZ = v.z();
      return *this;
   }

   /**
      Exact equality
   */
   bool operator == (const Cartesian3D & rhs) const {
      return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ;
   }
   bool operator != (const Cartesian3D & rhs) const {return !(operator==(rhs));}


   // ============= Compatibility section ==================

   // The following make this coordinate system look enough like a CLHEP
   // vector that an assignment member template can work with either
   T x() const { return X();}
   T y() const { return Y();}
   T z() const { return Z(); }

   // ============= Overloads for improved speed ==================

   template <class T2>
   explicit Cartesian3D( const Polar3D<T2> & v ) : fZ (v.Z())
   {
      T rho = v.Rho(); // re-using this instead of calling v.X() and v.Y()
      // is the speed improvement
      fX = rho * std::cos(v.Phi());
      fY = rho * std::sin(v.Phi());
   }
   // Technical note:  This works even though only Polar3Dfwd.h is
   // included (and in fact, including Polar3D.h would cause circularity
   // problems). It works because any program **using** this ctor must itself
   // be including Polar3D.h.

   template <class T2>
   Cartesian3D & operator = (const Polar3D<T2> & v)
   {
      T rho = v.Rho();
      fX = rho * std::cos(v.Phi());
      fY = rho * std::sin(v.Phi());
      fZ = v.Z();
      return *this;
   }



#if defined(__MAKECINT__) || defined(G__DICTIONARY)

   // ====== Set member functions for coordinates in other systems =======

   void SetR(Scalar r);

   void SetTheta(Scalar theta);

   void SetPhi(Scalar phi);

   void SetRho(Scalar rho);

   void SetEta(Scalar eta);

#endif


private:

   T fX;  // x coordinate
   T fY;  // y coordinate
   T fZ;  // z coordinate
};


  } // end namespace Math

} // end namespace ROOT


#if defined(__MAKECINT__) || defined(G__DICTIONARY)
// need to put here setter methods to resolve nasty cyclical dependencies
// I need to include other coordinate systems only when Cartesian is already defined
// since they depend on it
#ifndef ROOT_Math_GenVector_GenVector_exception
#include "Math/GenVector/GenVector_exception.h"
#endif
#ifndef ROOT_Math_GenVector_CylindricalEta3D
#include "Math/GenVector/CylindricalEta3D.h"
#endif
#ifndef ROOT_Math_GenVector_Polar3D
#include "Math/GenVector/Polar3D.h"
#endif

  // ====== Set member functions for coordinates in other systems =======

namespace ROOT {

  namespace Math {

template <class T>
void Cartesian3D<T>::SetR(Scalar r) {
   GenVector_exception e("Cartesian3D::SetR() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetR(r); *this = Cartesian3D<Scalar>(v);
}

template <class T>
void Cartesian3D<T>::SetTheta(Scalar theta) {
   GenVector_exception e("Cartesian3D::SetTheta() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetTheta(theta); *this = Cartesian3D<Scalar>(v);
}

template <class T>
void Cartesian3D<T>::SetPhi(Scalar phi) {
   GenVector_exception e("Cartesian3D::SetPhi() is not supposed to be called");
   throw e;
   Polar3D<Scalar> v(*this); v.SetPhi(phi); *this = Cartesian3D<Scalar>(v);
}

template <class T>
void Cartesian3D<T>::SetRho(Scalar rho) {
   GenVector_exception e("Cartesian3D::SetRho() is not supposed to be called");
   throw e;
   CylindricalEta3D<Scalar> v(*this); v.SetRho(rho);
   *this = Cartesian3D<Scalar>(v);
}

template <class T>
void Cartesian3D<T>::SetEta(Scalar eta) {
   GenVector_exception e("Cartesian3D::SetEta() is not supposed to be called");
   throw e;
   CylindricalEta3D<Scalar> v(*this); v.SetEta(eta);
    *this = Cartesian3D<Scalar>(v);
}



  } // end namespace Math

} // end namespace ROOT

#endif




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