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