ROOT  6.06/09
Reference Guide
DisplacementVector2D.h
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Authors: W. Brown, M. Fischler, L. Moneta 2005
3 
4  /**********************************************************************
5  * *
6  * Copyright (c) 2005 , LCG ROOT MathLib Team and *
7  * FNAL LCG ROOT MathLib Team *
8  * *
9  * *
10  **********************************************************************/
11 
12 // Header source file for class DisplacementVector2D
13 //
14 // Created by: Lorenzo Moneta at Mon Apr 16 2007
15 //
16 
17 #ifndef ROOT_Math_GenVector_DisplacementVector2D
18 #define ROOT_Math_GenVector_DisplacementVector2D 1
19 
20 #ifndef ROOT_Math_GenVector_Cartesian2D
22 #endif
23 
24 #ifndef ROOT_Math_GenVector_PositionVector2Dfwd
26 #endif
27 
28 #ifndef ROOT_Math_GenVector_GenVectorIO
30 #endif
31 
32 #ifndef ROOT_Math_GenVector_BitReproducible
34 #endif
35 
36 #ifndef ROOT_Math_GenVector_CoordinateSystemTags
38 #endif
39 
40 //#include "Math/GenVector/Expression2D.h"
41 
42 
43 
44 
45 namespace ROOT {
46 
47  namespace Math {
48 
49 
50 
51 //__________________________________________________________________________________________
52  /**
53  Class describing a generic displacement vector in 2 dimensions.
54  This class is templated on the type of Coordinate system.
55  One example is the XYVector which is a vector based on
56  double precision x,y data members by using the
57  ROOT::Math::Cartesian2D<double> Coordinate system.
58  The class is having also an extra template parameter, the coordinate system tag,
59  to be able to identify (tag) vector described in different reference coordinate system,
60  like global or local coordinate systems.
61 
62  @ingroup GenVector
63  */
64 
65  template <class CoordSystem, class Tag = DefaultCoordinateSystemTag >
67 
68  public:
69 
70  typedef typename CoordSystem::Scalar Scalar;
71  typedef CoordSystem CoordinateType;
72  typedef Tag CoordinateSystemTag;
73 
74  // ------ ctors ------
75 
76  /**
77  Default constructor. Construct an empty object with zero values
78  */
80 
81 
82  /**
83  Construct from three values of type <em>Scalar</em>.
84  In the case of a XYVector the values are x,y
85  In the case of a polar vector they are r, phi
86  */
87  DisplacementVector2D(Scalar a, Scalar b) :
88  fCoordinates ( a , b ) { }
89 
90  /**
91  Construct from a displacement vector expressed in different
92  coordinates, or using a different Scalar type, but with same coordinate system tag
93  */
94  template <class OtherCoords>
96  fCoordinates ( v.Coordinates() ) { }
97 
98 
99  /**
100  Construct from a position vector expressed in different coordinates
101  but with the same coordinate system tag
102  */
103  template <class OtherCoords>
105  fCoordinates ( p.Coordinates() ) { }
106 
107 
108  /**
109  Construct from a foreign 2D vector type, for example, Hep2Vector
110  Precondition: v must implement methods x() and y()
111  */
112  template <class ForeignVector>
113  explicit DisplacementVector2D( const ForeignVector & v) :
114  fCoordinates ( Cartesian2D<Scalar>( v.x(), v.y() ) ) { }
115 
116 
117 
118  // compiler-generated copy ctor and dtor are fine.
119 
120  // ------ assignment ------
121 
122  /**
123  Assignment operator from a displacement vector of arbitrary type
124  */
125  template <class OtherCoords>
126  DisplacementVector2D & operator=
128  fCoordinates = v.Coordinates();
129  return *this;
130  }
131 
132  /**
133  Assignment operator from a position vector
134  (not necessarily efficient unless one or the other is Cartesian)
135  */
136  template <class OtherCoords>
137  DisplacementVector2D & operator=
139  SetXY(rhs.x(), rhs.y() );
140  return *this;
141  }
142 
143 
144  /**
145  Assignment from a foreign 2D vector type, for example, Hep2Vector
146  Precondition: v must implement methods x() and y()
147  */
148  template <class ForeignVector>
149  DisplacementVector2D & operator= ( const ForeignVector & v) {
150  SetXY( v.x(), v.y() );
151  return *this;
152  }
153 
154 
155  // ------ Set, Get, and access coordinate data ------
156 
157  /**
158  Retrieve a copy of the coordinates object
159  */
160  CoordSystem Coordinates() const {
161  return fCoordinates;
162  }
163 
164  /**
165  Set internal data based on 2 Scalar numbers.
166  These are for example (x,y) for a cartesian vector or (r,phi) for a polar vector
167  */
169  fCoordinates.SetCoordinates(a, b);
170  return *this;
171  }
172 
173 
174  /**
175  get internal data into 2 Scalar numbers.
176  These are for example (x,y) for a cartesian vector or (r,phi) for a polar vector
177  */
178  void GetCoordinates( Scalar& a, Scalar& b) const
179  { fCoordinates.GetCoordinates(a, b); }
180 
181 
182  /**
183  set the values of the vector from the cartesian components (x,y)
184  (if the vector is held in polar coordinates,
185  then (x, y) are converted to that form)
186  */
188  fCoordinates.SetXY(a,b);
189  return *this;
190  }
191 
192  // ------------------- Equality -----------------
193 
194  /**
195  Exact equality
196  */
197  bool operator==(const DisplacementVector2D & rhs) const {
198  return fCoordinates==rhs.fCoordinates;
199  }
200  bool operator!= (const DisplacementVector2D & rhs) const {
201  return !(operator==(rhs));
202  }
203 
204  // ------ Individual element access, in various coordinate systems ------
205 
206  /**
207  Cartesian X, converting if necessary from internal coordinate system.
208  */
209  Scalar X() const { return fCoordinates.X(); }
210 
211  /**
212  Cartesian Y, converting if necessary from internal coordinate system.
213  */
214  Scalar Y() const { return fCoordinates.Y(); }
215 
216 
217  /**
218  Polar R, converting if necessary from internal coordinate system.
219  */
220  Scalar R() const { return fCoordinates.R(); }
221 
222 
223  /**
224  Polar phi, converting if necessary from internal coordinate system.
225  */
226  Scalar Phi() const { return fCoordinates.Phi(); }
227 
228 
229  // ----- Other fundamental properties -----
230 
231  /**
232  Magnitute squared ( r^2 in spherical coordinate)
233  */
234  Scalar Mag2() const { return fCoordinates.Mag2();}
235 
236 
237  /**
238  return unit vector parallel to this
239  */
241  Scalar tot = R();
242  return tot == 0 ? *this : DisplacementVector2D(*this) / tot;
243  }
244 
245  // ------ Setting individual elements present in coordinate system ------
246 
247  /**
248  Change X - Cartesian2D coordinates only
249  */
251  fCoordinates.SetX(a);
252  return *this;
253  }
254 
255  /**
256  Change Y - Cartesian2D coordinates only
257  */
259  fCoordinates.SetY(a);
260  return *this;
261  }
262 
263 
264  /**
265  Change R - Polar2D coordinates only
266  */
268  fCoordinates.SetR(a);
269  return *this;
270  }
271 
272 
273  /**
274  Change Phi - Polar2D coordinates
275  */
277  fCoordinates.SetPhi(ang);
278  return *this;
279  }
280 
281 
282 
283  // ------ Operations combining two vectors ------
284  // -- need to have the specialized version in order to avoid
285 
286  /**
287  Return the scalar (dot) product of two displacement vectors.
288  It is possible to perform the product for any type of vector coordinates,
289  but they must have the same coordinate system tag
290  */
291  template< class OtherCoords >
292  Scalar Dot( const DisplacementVector2D<OtherCoords,Tag> & v) const {
293  return X()*v.X() + Y()*v.Y();
294  }
295  /**
296  Return the scalar (dot) product of two vectors.
297  It is possible to perform the product for any classes
298  implementing x() and y() member functions
299  */
300  template< class OtherVector >
301  Scalar Dot( const OtherVector & v) const {
302  return X()*v.x() + Y()*v.y();
303  }
304 
305 
306 
307  /**
308  Self Addition with a displacement vector.
309  */
310  template <class OtherCoords>
311  DisplacementVector2D & operator+=
313  SetXY( X() + v.X(), Y() + v.Y() );
314  return *this;
315  }
316 
317  /**
318  Self Difference with a displacement vector.
319  */
320  template <class OtherCoords>
321  DisplacementVector2D & operator-=
323  SetXY( x() - v.x(), y() - v.y() );
324  return *this;
325  }
326 
327 
328  /**
329  multiply this vector by a scalar quantity
330  */
332  fCoordinates.Scale(a);
333  return *this;
334  }
335 
336  /**
337  divide this vector by a scalar quantity
338  */
340  fCoordinates.Scale(1/a);
341  return *this;
342  }
343 
344  // -- The following methods (v*a and v/a) could instead be free functions.
345  // -- They were moved into the class to solve a problem on AIX.
346 
347  /**
348  Multiply a vector by a real number
349  */
351  DisplacementVector2D tmp(*this);
352  tmp *= a;
353  return tmp;
354  }
355 
356  /**
357  Negative of the vector
358  */
360  return operator*( Scalar(-1) );
361  }
362 
363  /**
364  Positive of the vector, return itself
365  */
366  DisplacementVector2D operator + ( ) const {return *this;}
367 
368  /**
369  Division of a vector with a real number
370  */
372  DisplacementVector2D tmp(*this);
373  tmp /= a;
374  return tmp;
375  }
376 
377  /**
378  Rotate by an angle
379  */
380  void Rotate( Scalar angle) {
381  return fCoordinates.Rotate(angle);
382  }
383 
384 
385  // Methods providing Limited backward name compatibility with CLHEP
386 
387  Scalar x() const { return fCoordinates.X(); }
388  Scalar y() const { return fCoordinates.Y(); }
389  Scalar r() const { return fCoordinates.R(); }
390  Scalar phi() const { return fCoordinates.Phi(); }
391  Scalar mag2() const { return fCoordinates.Mag2(); }
392  DisplacementVector2D unit() const {return Unit();}
393 
394 
395  private:
396 
397  CoordSystem fCoordinates; // internal coordinate system
398 
399 
400  // the following methods should not compile
401 
402  // this should not compile (if from a vector or points with different tag
403  template <class OtherCoords, class OtherTag>
405 
406  template <class OtherCoords, class OtherTag>
408 
409  template <class OtherCoords, class OtherTag>
411 
412 
413  template <class OtherCoords, class OtherTag>
415 
416  template <class OtherCoords, class OtherTag>
418 
419  template <class OtherCoords, class OtherTag>
421 
422  template<class OtherCoords, class OtherTag >
423  Scalar Dot( const DisplacementVector2D<OtherCoords, OtherTag> & ) const;
424 
425  template<class OtherCoords, class OtherTag >
427 
428 
429  };
430 
431 // ---------- DisplacementVector2D class template ends here ------------
432 // ---------------------------------------------------------------------
433 
434 
435  /**
436  Addition of DisplacementVector2D vectors.
437  The (coordinate system) type of the returned vector is defined to
438  be identical to that of the first vector, which is passed by value
439  */
440  template <class CoordSystem1, class CoordSystem2, class U>
441  inline
442  DisplacementVector2D<CoordSystem1,U>
445  return v1 += v2;
446  }
447 
448  /**
449  Difference between two DisplacementVector2D vectors.
450  The (coordinate system) type of the returned vector is defined to
451  be identical to that of the first vector.
452  */
453  template <class CoordSystem1, class CoordSystem2, class U>
454  inline
455  DisplacementVector2D<CoordSystem1,U>
458  return v1 -= v2;
459  }
460 
461 
462 
463 
464 
465  /**
466  Multiplication of a displacement vector by real number a*v
467  */
468  template <class CoordSystem, class U>
469  inline
470  DisplacementVector2D<CoordSystem,U>
473  return v *= a;
474  // Note - passing v by value and using operator *= may save one
475  // copy relative to passing v by const ref and creating a temporary.
476  }
477 
478 
479  // v1*v2 notation for Cross product of two vectors is omitted,
480  // since it is always confusing as to whether dot product is meant.
481 
482 
483 
484  // ------------- I/O to/from streams -------------
485 
486  template< class char_t, class traits_t, class T, class U >
487  inline
488  std::basic_ostream<char_t,traits_t> &
489  operator << ( std::basic_ostream<char_t,traits_t> & os
490  , DisplacementVector2D<T,U> const & v
491  )
492  {
493  if( !os ) return os;
494 
495  typename T::Scalar a, b;
496  v.GetCoordinates(a, b);
497 
498  if( detail::get_manip( os, detail::bitforbit ) ) {
499  detail::set_manip( os, detail::bitforbit, '\00' );
501  BR::Output(os, a);
502  BR::Output(os, b);
503  }
504  else {
505  os << detail::get_manip( os, detail::open ) << a
506  << detail::get_manip( os, detail::sep ) << b
508  }
509 
510  return os;
511 
512  } // op<< <>()
513 
514 
515  template< class char_t, class traits_t, class T, class U >
516  inline
517  std::basic_istream<char_t,traits_t> &
518  operator >> ( std::basic_istream<char_t,traits_t> & is
520  )
521  {
522  if( !is ) return is;
523 
524  typename T::Scalar a, b;
525 
526  if( detail::get_manip( is, detail::bitforbit ) ) {
527  detail::set_manip( is, detail::bitforbit, '\00' );
529  BR::Input(is, a);
530  BR::Input(is, b);
531  }
532  else {
533  detail::require_delim( is, detail::open ); is >> a;
534  detail::require_delim( is, detail::sep ); is >> b;
536  }
537 
538  if( is )
539  v.SetCoordinates(a, b);
540  return is;
541 
542  } // op>> <>()
543 
544 
545 
546  } // namespace Math
547 
548 } // namespace ROOT
549 
550 
551 #endif /* ROOT_Math_GenVector_DisplacementVector2D */
552 
DisplacementVector2D()
Default constructor.
Scalar Dot(const OtherVector &v) const
Return the scalar (dot) product of two vectors.
DisplacementVector2D & operator/=(Scalar a)
divide this vector by a scalar quantity
const Double_t * v1
Definition: TArcBall.cxx:33
Scalar Mag2() const
Magnitute squared ( r^2 in spherical coordinate)
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
CoordSystem Coordinates() const
Retrieve a copy of the coordinates object.
DisplacementVector2D< CoordSystem, Tag > & SetY(Scalar a)
Change Y - Cartesian2D coordinates only.
Scalar Phi() const
Polar phi, converting if necessary from internal coordinate system.
std::basic_istream< char_t, traits_t > & operator>>(std::basic_istream< char_t, traits_t > &is, DisplacementVector2D< T, U > &v)
DisplacementVector2D< CoordSystem, Tag > & SetCoordinates(Scalar a, Scalar b)
Set internal data based on 2 Scalar numbers.
TArc * a
Definition: textangle.C:12
DisplacementVector2D Unit() const
return unit vector parallel to this
DisplacementVector2D(const PositionVector2D< OtherCoords, OtherTag > &)
DisplacementVector2D< CoordSystem1, U > operator+(DisplacementVector2D< CoordSystem1, U > v1, const DisplacementVector2D< CoordSystem2, U > &v2)
Addition of DisplacementVector2D vectors.
DisplacementVector2D & operator=(const DisplacementVector2D< OtherCoords, Tag > &v)
Assignment operator from a displacement vector of arbitrary type.
DisplacementVector2D< CoordSystem1, U > operator-(DisplacementVector2D< CoordSystem1, U > v1, DisplacementVector2D< CoordSystem2, U > const &v2)
Difference between two DisplacementVector2D vectors.
DisplacementVector2D(const DisplacementVector2D< OtherCoords, Tag > &v)
Construct from a displacement vector expressed in different coordinates, or using a different Scalar ...
Scalar Y() const
Cartesian Y, converting if necessary from internal coordinate system.
DisplacementVector2D operator/(Scalar a) const
Division of a vector with a real number.
DisplacementVector2D operator*(Scalar a) const
Multiply a vector by a real number.
void Rotate(Scalar angle)
Rotate by an angle.
char_t get_manip(std::basic_ios< char_t, traits_t > &ios, manip_t m)
Definition: GenVectorIO.h:54
bool operator!=(const DisplacementVector2D &rhs) const
Scalar Dot(const DisplacementVector2D< OtherCoords, Tag > &v) const
Return the scalar (dot) product of two displacement vectors.
DisplacementVector2D & operator+=(const DisplacementVector2D< OtherCoords, Tag > &v)
Self Addition with a displacement vector.
SVector< double, 2 > v
Definition: Dict.h:5
DisplacementVector2D operator-() const
Negative of the vector.
DisplacementVector2D(const PositionVector2D< OtherCoords, Tag > &p)
Construct from a position vector expressed in different coordinates but with the same coordinate syst...
Scalar R() const
Polar R, converting if necessary from internal coordinate system.
#define Scalar
Definition: global.h:83
void GetCoordinates(Scalar &a, Scalar &b) const
get internal data into 2 Scalar numbers.
DisplacementVector2D unit() const
DisplacementVector2D< CoordSystem, Tag > & SetR(Scalar a)
Change R - Polar2D coordinates only.
Class describing a generic position vector (point) in 2 dimensions.
DisplacementVector2D(const DisplacementVector2D< OtherCoords, OtherTag > &)
DisplacementVector2D< CoordSystem, Tag > & SetX(Scalar a)
Change X - Cartesian2D coordinates only.
DisplacementVector2D< CoordSystem, Tag > & SetXY(Scalar a, Scalar b)
set the values of the vector from the cartesian components (x,y) (if the vector is held in polar coor...
DisplacementVector2D< CoordSystem, Tag > & SetPhi(Scalar ang)
Change Phi - Polar2D coordinates.
Class describing a 2D cartesian coordinate system (x, y coordinates)
Definition: Cartesian2D.h:41
void set_manip(std::basic_ios< char_t, traits_t > &ios, manip_t m, char_t ch)
Definition: GenVectorIO.h:74
Namespace for new Math classes and functions.
DisplacementVector2D Cross(const DisplacementVector2D< OtherCoords, OtherTag > &) const
Scalar X() const
Cartesian X, converting if necessary from internal coordinate system.
std::basic_istream< char_t, traits_t > & require_delim(std::basic_istream< char_t, traits_t > &is, manip_t m)
Definition: GenVectorIO.h:113
bool operator==(const DisplacementVector2D &rhs) const
Exact equality.
DisplacementVector2D(Scalar a, Scalar b)
Construct from three values of type Scalar.
DisplacementVector2D(const ForeignVector &v)
Construct from a foreign 2D vector type, for example, Hep2Vector Precondition: v must implement metho...
DisplacementVector2D & operator*=(Scalar a)
multiply this vector by a scalar quantity
DisplacementVector2D & operator-=(const DisplacementVector2D< OtherCoords, Tag > &v)
Self Difference with a displacement vector.
Class describing a generic displacement vector in 2 dimensions.
DisplacementVector2D operator+() const
Positive of the vector, return itself.
AxisAngle operator*(RotationX const &r1, AxisAngle const &r2)
Multiplication of an axial rotation by an AxisAngle.