File indexing completed on 2025-12-25 10:02:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef ROOT_Math_GenVector_DisplacementVector3D
0021 #define ROOT_Math_GenVector_DisplacementVector3D 1
0022
0023 #include "Math/GenVector/Cartesian3D.h"
0024
0025 #include "Math/GenVector/PositionVector3Dfwd.h"
0026
0027 #include "Math/GenVector/GenVectorIO.h"
0028
0029 #include "Math/GenVector/BitReproducible.h"
0030
0031 #include "Math/GenVector/CoordinateSystemTags.h"
0032
0033 #include <cassert>
0034
0035
0036 namespace ROOT {
0037
0038 namespace Math {
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057 template <class CoordSystem, class Tag = DefaultCoordinateSystemTag >
0058 class DisplacementVector3D {
0059
0060 public:
0061
0062 typedef typename CoordSystem::Scalar Scalar;
0063 typedef CoordSystem CoordinateType;
0064 typedef Tag CoordinateSystemTag;
0065
0066
0067
0068
0069
0070
0071 constexpr DisplacementVector3D ( ) : fCoordinates() { }
0072
0073
0074
0075
0076
0077
0078
0079 constexpr DisplacementVector3D(Scalar a, Scalar b, Scalar c) :
0080 fCoordinates ( a , b, c ) { }
0081
0082
0083
0084
0085
0086 template <class OtherCoords>
0087 explicit constexpr DisplacementVector3D( const DisplacementVector3D<OtherCoords, Tag> & v) :
0088 fCoordinates ( v.Coordinates() ) { }
0089
0090
0091
0092
0093
0094
0095 template <class OtherCoords>
0096 explicit constexpr DisplacementVector3D( const PositionVector3D<OtherCoords,Tag> & p) :
0097 fCoordinates ( p.Coordinates() ) { }
0098
0099
0100
0101
0102
0103
0104 template <class ForeignVector>
0105 explicit constexpr DisplacementVector3D( const ForeignVector & v) :
0106 fCoordinates ( Cartesian3D<Scalar>( v.x(), v.y(), v.z() ) ) { }
0107
0108
0109 #ifdef LATER
0110
0111
0112
0113
0114
0115
0116
0117
0118 template <class LAVector>
0119 constexpr DisplacementVector3D(const LAVector & v, size_t index0 ) {
0120 fCoordinates = CoordSystem ( v[index0], v[index0+1], v[index0+2] );
0121 }
0122 #endif
0123
0124
0125
0126
0127
0128
0129
0130
0131 template <class OtherCoords>
0132 DisplacementVector3D & operator=
0133 ( const DisplacementVector3D<OtherCoords, Tag> & v) {
0134 fCoordinates = v.Coordinates();
0135 return *this;
0136 }
0137
0138
0139
0140
0141
0142 template <class OtherCoords>
0143 DisplacementVector3D & operator=
0144 ( const PositionVector3D<OtherCoords,Tag> & rhs) {
0145 SetXYZ(rhs.x(), rhs.y(), rhs.z());
0146 return *this;
0147 }
0148
0149
0150
0151
0152
0153
0154 template <class ForeignVector>
0155 DisplacementVector3D & operator= ( const ForeignVector & v) {
0156 SetXYZ( v.x(), v.y(), v.z() );
0157 return *this;
0158 }
0159
0160
0161 #ifdef LATER
0162
0163
0164
0165
0166
0167
0168
0169
0170 template <class LAVector>
0171 DisplacementVector3D & assignFrom(const LAVector & v, size_t index0 = 0) {
0172 fCoordinates = CoordSystem ( v[index0], v[index0+1], v[index0+2] );
0173 return *this;
0174 }
0175 #endif
0176
0177
0178
0179
0180
0181
0182 CoordSystem Coordinates() const {
0183 return fCoordinates;
0184 }
0185
0186
0187
0188
0189 DisplacementVector3D<CoordSystem, Tag>& SetCoordinates( const Scalar src[] )
0190 { fCoordinates.SetCoordinates(src); return *this; }
0191
0192
0193
0194
0195 DisplacementVector3D<CoordSystem, Tag>& SetCoordinates( Scalar a, Scalar b, Scalar c )
0196 { fCoordinates.SetCoordinates(a, b, c); return *this; }
0197
0198
0199
0200
0201 template <class IT>
0202 DisplacementVector3D<CoordSystem, Tag>& SetCoordinates( IT begin, IT end )
0203 { IT a = begin; IT b = ++begin; IT c = ++begin;
0204 (void)end;
0205 assert (++begin==end);
0206 SetCoordinates (*a,*b,*c);
0207 return *this;
0208 }
0209
0210
0211
0212
0213
0214 void GetCoordinates( Scalar& a, Scalar& b, Scalar& c ) const
0215 { fCoordinates.GetCoordinates(a, b, c); }
0216
0217
0218
0219
0220 void GetCoordinates( Scalar dest[] ) const
0221 { fCoordinates.GetCoordinates(dest); }
0222
0223
0224
0225
0226 template <class IT>
0227 void GetCoordinates( IT begin, IT end ) const
0228 { IT a = begin; IT b = ++begin; IT c = ++begin;
0229 (void)end;
0230 assert (++begin==end);
0231 GetCoordinates (*a,*b,*c);
0232 }
0233
0234
0235
0236 template <class IT>
0237 void GetCoordinates( IT begin) const {
0238 Scalar a = Scalar(0);
0239 Scalar b = Scalar(0);
0240 Scalar c = Scalar(0);
0241 GetCoordinates(a, b, c);
0242 *begin++ = a;
0243 *begin++ = b;
0244 *begin = c;
0245 }
0246
0247
0248
0249
0250
0251
0252 DisplacementVector3D<CoordSystem, Tag>& SetXYZ (Scalar a, Scalar b, Scalar c) {
0253 fCoordinates.SetXYZ(a, b, c);
0254 return *this;
0255 }
0256
0257
0258
0259
0260
0261
0262 bool operator==(const DisplacementVector3D & rhs) const {
0263 return fCoordinates==rhs.fCoordinates;
0264 }
0265 bool operator!= (const DisplacementVector3D & rhs) const {
0266 return !(operator==(rhs));
0267 }
0268
0269
0270
0271
0272
0273
0274 unsigned int Dimension() const
0275 {
0276 return fDimension;
0277 };
0278
0279
0280
0281
0282 Scalar X() const { return fCoordinates.X(); }
0283
0284
0285
0286
0287 Scalar Y() const { return fCoordinates.Y(); }
0288
0289
0290
0291
0292 Scalar Z() const { return fCoordinates.Z(); }
0293
0294
0295
0296
0297 Scalar R() const { return fCoordinates.R(); }
0298
0299
0300
0301
0302 Scalar Theta() const { return fCoordinates.Theta(); }
0303
0304
0305
0306
0307 Scalar Phi() const { return fCoordinates.Phi(); }
0308
0309
0310
0311
0312 Scalar Eta() const { return fCoordinates.Eta(); }
0313
0314
0315
0316
0317 Scalar Rho() const { return fCoordinates.Rho(); }
0318
0319
0320
0321
0322
0323
0324 Scalar Mag2() const { return fCoordinates.Mag2();}
0325
0326
0327
0328
0329 Scalar Perp2() const { return fCoordinates.Perp2();}
0330
0331
0332
0333
0334 template <typename SCALAR = Scalar, typename std::enable_if<std::is_arithmetic<SCALAR>::value>::type * = nullptr>
0335 DisplacementVector3D Unit() const
0336 {
0337 const auto tot = R();
0338 return tot == 0 ? *this : DisplacementVector3D(*this) / tot;
0339 }
0340
0341
0342
0343
0344 template <typename SCALAR = Scalar, typename std::enable_if<!std::is_arithmetic<SCALAR>::value>::type * = nullptr>
0345 DisplacementVector3D Unit() const
0346 {
0347 SCALAR tot = R();
0348 tot(tot == SCALAR(0)) = SCALAR(1);
0349 return DisplacementVector3D(*this) / tot;
0350 }
0351
0352
0353
0354
0355
0356
0357 DisplacementVector3D<CoordSystem, Tag>& SetX (Scalar xx) { fCoordinates.SetX(xx); return *this;}
0358
0359
0360
0361
0362 DisplacementVector3D<CoordSystem, Tag>& SetY (Scalar yy) { fCoordinates.SetY(yy); return *this;}
0363
0364
0365
0366
0367 DisplacementVector3D<CoordSystem, Tag>& SetZ (Scalar zz) { fCoordinates.SetZ(zz); return *this;}
0368
0369
0370
0371
0372 DisplacementVector3D<CoordSystem, Tag>& SetR (Scalar rr) { fCoordinates.SetR(rr); return *this;}
0373
0374
0375
0376
0377 DisplacementVector3D<CoordSystem, Tag>& SetTheta (Scalar ang) { fCoordinates.SetTheta(ang); return *this;}
0378
0379
0380
0381
0382 DisplacementVector3D<CoordSystem, Tag>& SetPhi (Scalar ang) { fCoordinates.SetPhi(ang); return *this;}
0383
0384
0385
0386
0387 DisplacementVector3D<CoordSystem, Tag>& SetRho (Scalar rr) { fCoordinates.SetRho(rr); return *this;}
0388
0389
0390
0391
0392 DisplacementVector3D<CoordSystem, Tag>& SetEta (Scalar etaval) { fCoordinates.SetEta(etaval); return *this;}
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403 template< class OtherCoords >
0404 Scalar Dot( const DisplacementVector3D<OtherCoords,Tag> & v) const {
0405 return X()*v.X() + Y()*v.Y() + Z()*v.Z();
0406 }
0407
0408
0409
0410
0411
0412 template< class OtherVector >
0413 Scalar Dot( const OtherVector & v) const {
0414 return X()*v.x() + Y()*v.y() + Z()*v.z();
0415 }
0416
0417
0418
0419
0420
0421
0422
0423 template <class OtherCoords>
0424 DisplacementVector3D Cross( const DisplacementVector3D<OtherCoords,Tag> & v) const {
0425 DisplacementVector3D result;
0426 result.SetXYZ ( Y()*v.Z() - v.Y()*Z(),
0427 Z()*v.X() - v.Z()*X(),
0428 X()*v.Y() - v.X()*Y() );
0429 return result;
0430 }
0431
0432
0433
0434
0435
0436
0437 template <class OtherVector>
0438 DisplacementVector3D Cross( const OtherVector & v) const {
0439 DisplacementVector3D result;
0440 result.SetXYZ ( Y()*v.z() - v.y()*Z(),
0441 Z()*v.x() - v.z()*X(),
0442 X()*v.y() - v.x()*Y() );
0443 return result;
0444 }
0445
0446
0447
0448
0449
0450
0451 template <class OtherCoords>
0452 DisplacementVector3D & operator+=
0453 (const DisplacementVector3D<OtherCoords,Tag> & v) {
0454 SetXYZ( X() + v.X(), Y() + v.Y(), Z() + v.Z() );
0455 return *this;
0456 }
0457
0458
0459
0460
0461 template <class OtherCoords>
0462 DisplacementVector3D & operator-=
0463 (const DisplacementVector3D<OtherCoords,Tag> & v) {
0464 SetXYZ( x() - v.x(), y() - v.y(), z() - v.z() );
0465 return *this;
0466 }
0467
0468
0469
0470
0471
0472 DisplacementVector3D & operator*= (Scalar a) {
0473 fCoordinates.Scale(a);
0474 return *this;
0475 }
0476
0477
0478
0479
0480 DisplacementVector3D & operator/= (Scalar a) {
0481 fCoordinates.Scale(1/a);
0482 return *this;
0483 }
0484
0485
0486
0487
0488
0489
0490
0491 DisplacementVector3D operator * ( Scalar a ) const {
0492 DisplacementVector3D tmp(*this);
0493 tmp *= a;
0494 return tmp;
0495 }
0496
0497
0498
0499
0500 DisplacementVector3D operator - ( ) const {
0501 return operator*( Scalar(-1) );
0502 }
0503
0504
0505
0506
0507 DisplacementVector3D operator + ( ) const {return *this;}
0508
0509
0510
0511
0512 DisplacementVector3D operator/ (Scalar a) const {
0513 DisplacementVector3D tmp(*this);
0514 tmp /= a;
0515 return tmp;
0516 }
0517
0518
0519
0520
0521 Scalar x() const { return fCoordinates.X(); }
0522 Scalar y() const { return fCoordinates.Y(); }
0523 Scalar z() const { return fCoordinates.Z(); }
0524 Scalar r() const { return fCoordinates.R(); }
0525 Scalar theta() const { return fCoordinates.Theta(); }
0526 Scalar phi() const { return fCoordinates.Phi(); }
0527 Scalar eta() const { return fCoordinates.Eta(); }
0528 Scalar rho() const { return fCoordinates.Rho(); }
0529 Scalar mag2() const { return fCoordinates.Mag2(); }
0530 Scalar perp2() const { return fCoordinates.Perp2(); }
0531 DisplacementVector3D unit() const {return Unit();}
0532
0533
0534 private:
0535
0536 CoordSystem fCoordinates;
0537 static constexpr unsigned int fDimension = CoordinateType::Dimension;
0538
0539 #ifdef NOT_SURE_THIS_SHOULD_BE_FORBIDDEN
0540
0541
0542
0543 template <class T2>
0544 DisplacementVector3D Cross( const PositionVector3D<T2> & ) const;
0545 #endif
0546
0547
0548
0549
0550 template <class OtherCoords, class OtherTag>
0551 explicit constexpr DisplacementVector3D( const DisplacementVector3D<OtherCoords, OtherTag> & ) {}
0552
0553 template <class OtherCoords, class OtherTag>
0554 explicit constexpr DisplacementVector3D( const PositionVector3D<OtherCoords, OtherTag> & ) {}
0555
0556 template <class OtherCoords, class OtherTag>
0557 DisplacementVector3D & operator=( const DisplacementVector3D<OtherCoords, OtherTag> & );
0558
0559
0560 template <class OtherCoords, class OtherTag>
0561 DisplacementVector3D & operator=( const PositionVector3D<OtherCoords, OtherTag> & );
0562
0563 template <class OtherCoords, class OtherTag>
0564 DisplacementVector3D & operator+=(const DisplacementVector3D<OtherCoords, OtherTag> & );
0565
0566 template <class OtherCoords, class OtherTag>
0567 DisplacementVector3D & operator-=(const DisplacementVector3D<OtherCoords, OtherTag> & );
0568
0569 template<class OtherCoords, class OtherTag >
0570 Scalar Dot( const DisplacementVector3D<OtherCoords, OtherTag> & ) const;
0571
0572 template<class OtherCoords, class OtherTag >
0573 DisplacementVector3D Cross( const DisplacementVector3D<OtherCoords, OtherTag> & ) const;
0574
0575
0576 };
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588 template <class CoordSystem1, class CoordSystem2, class U>
0589 inline
0590 DisplacementVector3D<CoordSystem1,U>
0591 operator+( DisplacementVector3D<CoordSystem1,U> v1,
0592 const DisplacementVector3D<CoordSystem2,U> & v2) {
0593 return v1 += v2;
0594 }
0595
0596
0597
0598
0599
0600
0601 template <class CoordSystem1, class CoordSystem2, class U>
0602 inline
0603 DisplacementVector3D<CoordSystem1,U>
0604 operator-( DisplacementVector3D<CoordSystem1,U> v1,
0605 DisplacementVector3D<CoordSystem2,U> const & v2) {
0606 return v1 -= v2;
0607 }
0608
0609
0610
0611
0612 template <class CoordSystem, class U>
0613 inline
0614 DisplacementVector3D<CoordSystem,U>
0615 operator * ( typename DisplacementVector3D<CoordSystem,U>::Scalar a,
0616 DisplacementVector3D<CoordSystem,U> v) {
0617 return v *= a;
0618
0619
0620 }
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630 template <class char_t, class traits_t, class T, class U,
0631 typename std::enable_if<std::is_arithmetic<typename DisplacementVector3D<T, U>::Scalar>::value>::type * =
0632 nullptr>
0633 std::basic_ostream<char_t, traits_t> &operator<<(std::basic_ostream<char_t, traits_t> &os,
0634 DisplacementVector3D<T, U> const &v)
0635 {
0636 if (os) {
0637
0638 typename T::Scalar a, b, c;
0639 v.GetCoordinates(a, b, c);
0640
0641 if (detail::get_manip(os, detail::bitforbit)) {
0642 detail::set_manip(os, detail::bitforbit, '\00');
0643 typedef GenVector_detail::BitReproducible BR;
0644 BR::Output(os, a);
0645 BR::Output(os, b);
0646 BR::Output(os, c);
0647 } else {
0648 os << detail::get_manip(os, detail::open) << a << detail::get_manip(os, detail::sep) << b
0649 << detail::get_manip(os, detail::sep) << c << detail::get_manip(os, detail::close);
0650 }
0651 }
0652 return os;
0653 }
0654
0655 template <class char_t, class traits_t, class T, class U,
0656 typename std::enable_if<!std::is_arithmetic<typename DisplacementVector3D<T, U>::Scalar>::value>::type * =
0657 nullptr>
0658 std::basic_ostream<char_t, traits_t> &operator<<(std::basic_ostream<char_t, traits_t> &os,
0659 DisplacementVector3D<T, U> const &v)
0660 {
0661 if (os) {
0662 os << "{ ";
0663 for (std::size_t i = 0; i < PositionVector3D<T, U>::Scalar::Size; ++i) {
0664 os << "(" << v.x()[i] << "," << v.y()[i] << "," << v.z()[i] << ") ";
0665 }
0666 os << "}";
0667 }
0668 return os;
0669 }
0670
0671 template< class char_t, class traits_t, class T, class U >
0672 inline
0673 std::basic_istream<char_t,traits_t> &
0674 operator >> ( std::basic_istream<char_t,traits_t> & is
0675 , DisplacementVector3D<T,U> & v
0676 )
0677 {
0678 if( !is ) return is;
0679
0680 typename T::Scalar a, b, c;
0681
0682 if( detail::get_manip( is, detail::bitforbit ) ) {
0683 detail::set_manip( is, detail::bitforbit, '\00' );
0684 typedef GenVector_detail::BitReproducible BR;
0685 BR::Input(is, a);
0686 BR::Input(is, b);
0687 BR::Input(is, c);
0688 }
0689 else {
0690 detail::require_delim( is, detail::open ); is >> a;
0691 detail::require_delim( is, detail::sep ); is >> b;
0692 detail::require_delim( is, detail::sep ); is >> c;
0693 detail::require_delim( is, detail::close );
0694 }
0695
0696 if( is )
0697 v.SetCoordinates(a, b, c);
0698 return is;
0699
0700 }
0701
0702
0703 template <std::size_t I, class CoordSystem, class Tag>
0704 typename CoordSystem::Scalar get(DisplacementVector3D<CoordSystem, Tag> const& p)
0705 {
0706 static_assert(I < 3);
0707 if constexpr (I == 0) {
0708 return p.x();
0709 } else if constexpr (I == 1) {
0710 return p.y();
0711 } else {
0712 return p.z();
0713 }
0714 }
0715
0716 }
0717
0718 }
0719
0720
0721 #include <tuple>
0722 namespace std {
0723 template <class CoordSystem, class Tag>
0724 struct tuple_size<ROOT::Math::DisplacementVector3D<CoordSystem, Tag>> : integral_constant<size_t, 3> {};
0725 template <size_t I, class CoordSystem, class Tag>
0726 struct tuple_element<I, ROOT::Math::DisplacementVector3D<CoordSystem, Tag>> {
0727 static_assert(I < 3);
0728 using type = typename CoordSystem::Scalar;
0729 };
0730 }
0731
0732 #endif
0733