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

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

// Header file for class Translation3D
//
// Created by: Lorenzo Moneta  October 21 2005
//
//
#ifndef ROOT_Math_GenVector_Translation3D
#define ROOT_Math_GenVector_Translation3D  1


#ifndef ROOT_Math_GenVector_DisplacementVector3D
#include "Math/GenVector/DisplacementVector3D.h"
#endif

#ifndef ROOT_Math_GenVector_PositionVector3Dfwd
#include "Math/GenVector/PositionVector3Dfwd.h"
#endif

#ifndef ROOT_Math_GenVector_LorentzVectorfwd
#include "Math/GenVector/LorentzVectorfwd.h"
#endif

#include <iostream>



namespace ROOT {

namespace Math {


   class Plane3D;


//____________________________________________________________________________________________________
/**
    Class describing a 3 dimensional translation. It can be combined (using the operator *)
    with the ROOT::Math::Rotation3D  classes and ROOT::Math::Transform3D to obtained combined
    transformations and to operate on points and vectors.
    Note that a the translation applied to a Vector object (DisplacementVector3D and LorentzVector classes)
    performes a noop, i.e. it returns the same vector. A translation can be applied only to the Point objects
    (PositionVector3D classes).

    @ingroup GenVector

*/

class Translation3D {


  public:

    typedef  DisplacementVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag >  Vector;




   /**
       Default constructor ( zero translation )
   */
   Translation3D() {}

   /**
      Construct given a pair of pointers or iterators defining the
      beginning and end of an array of 3 Scalars representing the z,y,z of the translation vector
   */
   template<class IT>
   Translation3D(IT begin, IT end)
   {
      fVect.SetCoordinates(begin,end);
   }

   /**
      Construct from x,y,z values representing the translation
   */
   Translation3D(double dx, double dy, double dz) :
      fVect( Vector(dx, dy, dz) )
   {  }


   /**
      Construct from any Displacement vector in ant tag and coordinate system
   */
   template<class CoordSystem, class Tag>
   explicit Translation3D( const DisplacementVector3D<CoordSystem,Tag> & v) :
      fVect(Vector(v.X(),v.Y(),v.Z()))
   { }


   /**
      Construct transformation from one coordinate system defined one point (the origin)
       to a new coordinate system defined by other point (origin )
      @param p1  point defining origin of original reference system
      @param p2  point defining origin of transformed reference system

   */
   template<class CoordSystem, class Tag>
   Translation3D (const  PositionVector3D<CoordSystem,Tag> & p1, const PositionVector3D<CoordSystem,Tag> & p2 ) :
      fVect(p2-p1)
   { }


   // use compiler generated copy ctor, copy assignmet and dtor


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

   /**
       return a const reference to the underline vector representing the translation
   */
   const Vector & Vect() const { return fVect; }

   /**
      Set the 3  components given an iterator to the start of
      the desired data, and another to the end (3 past start).
   */
   template<class IT>
   void SetComponents(IT begin, IT end) {
      fVect.SetCoordinates(begin,end);
   }

   /**
      Get the 3  components into data specified by an iterator begin
      and another to the end of the desired data (12 past start).
   */
   template<class IT>
   void GetComponents(IT begin, IT end) const {
      fVect.GetCoordinates(begin,end);
   }

   /**
      Get the 3 matrix components into data specified by an iterator begin
   */
   template<class IT>
   void GetComponents(IT begin) const {
      fVect.GetCoordinates(begin);
   }


   /**
      Set the components from 3 scalars
   */
   void
   SetComponents (double  dx, double  dy, double  dz ) {
      fVect.SetCoordinates(dx,dy,dz);
   }

   /**
      Get the components into 3 scalars
   */
   void
   GetComponents (double &dx, double &dy, double &dz) const {
      fVect.GetCoordinates(dx,dy,dz);
   }


   /**
      Set the XYZ vector components from 3 scalars
   */
   void
   SetXYZ (double  dx, double  dy, double  dz ) {
      fVect.SetXYZ(dx,dy,dz);
   }


   // operations on points and vectors


   /**
      Transformation operation for Position Vector in any coordinate system and default tag
   */
   template<class CoordSystem, class Tag >
   PositionVector3D<CoordSystem,Tag> operator() (const PositionVector3D <CoordSystem,Tag> & p) const {
      PositionVector3D<CoordSystem,Tag>  tmp;
      tmp.SetXYZ (p.X() + fVect.X(),
                  p.Y() + fVect.Y(),
                  p.Z() + fVect.Z() ) ;
      return tmp;
   }

   /**
      Transformation operation for Displacement Vector in any coordinate system and default tag
      For the Displacement Vectors no translation apply so return the vector itself
   */
   template<class CoordSystem, class Tag >
   DisplacementVector3D<CoordSystem,Tag> operator() (const DisplacementVector3D <CoordSystem,Tag> & v) const {
      return  v;
   }

   /**
      Transformation operation for points between different coordinate system tags
   */
   template<class CoordSystem, class Tag1, class Tag2 >
   void Transform (const PositionVector3D <CoordSystem,Tag1> & p1, PositionVector3D <CoordSystem,Tag2> & p2  ) const {
      PositionVector3D <CoordSystem,Tag2> tmp;
      tmp.SetXYZ( p1.X(), p1.Y(), p1.Z() );
      p2 =  operator()(tmp);
    }


   /**
      Transformation operation for Displacement Vector of different coordinate systems
   */
   template<class CoordSystem,  class Tag1, class Tag2 >
   void Transform (const DisplacementVector3D <CoordSystem,Tag1> & v1, DisplacementVector3D <CoordSystem,Tag2> & v2  ) const {
      // just copy v1 in v2
      v2.SetXYZ(v1.X(), v1.Y(), v1.Z() );
   }

   /**
      Transformation operation for a Lorentz Vector in any  coordinate system
      A LorentzVector contains a displacement vector so no translation applies as well
   */
   template <class CoordSystem >
   LorentzVector<CoordSystem> operator() (const LorentzVector<CoordSystem> & q) const {
      return  q;
   }

   /**
      Transformation on a 3D plane
   */
   Plane3D operator() (const Plane3D & plane) const;


   /**
      Transformation operation for Vectors. Apply same rules as operator()
      depending on type of vector.
      Will work only for DisplacementVector3D, PositionVector3D and LorentzVector
   */
   template<class AVector >
   AVector operator * (const AVector & v) const {
      return operator() (v);
   }



   /**
      multiply (combine) with another transformation in place
   */
   Translation3D & operator *= (const Translation3D  & t) {
      fVect+= t.Vect();
      return *this;
   }

   /**
      multiply (combine) two transformations
   */
   Translation3D operator * (const Translation3D  & t) const {
      return Translation3D( fVect + t.Vect() );
   }

   /**
       Invert the transformation in place
   */
   void Invert() {
      SetComponents( -fVect.X(), -fVect.Y(),-fVect.Z() );
   }

   /**
      Return the inverse of the transformation.
   */
   Translation3D Inverse() const {
      return Translation3D( -fVect.X(), -fVect.Y(),-fVect.Z() );
   }


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

   bool operator != (const Translation3D & rhs) const {
      return ! operator==(rhs);
   }



private:

   Vector fVect;   // internal 3D vector representing the translation

};





// global functions

// TODO - I/O should be put in the manipulator form

std::ostream & operator<< (std::ostream & os, const Translation3D & t);

// need a function Transform = Translation * Rotation ???

   } // end namespace Math

} // end namespace ROOT


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