File indexing completed on 2026-09-18 09:32:41
0001
0002
0003
0004 #ifndef VECGEOM_BASE_VECTOR3D_H_
0005 #define VECGEOM_BASE_VECTOR3D_H_
0006
0007 #include "VecGeom/base/Global.h"
0008 #include "VecGeom/base/AlignedBase.h"
0009 #include "VecGeom/base/Vector2D.h"
0010
0011 #include <cstdlib>
0012 #include <ostream>
0013 #include <string>
0014
0015 namespace vecgeom {
0016
0017 VECGEOM_DEVICE_FORWARD_DECLARE(template <typename Type> class Vector3D;);
0018 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, Vector3D, typename);
0019
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021
0022
0023
0024
0025
0026
0027 template <typename Type>
0028 class Vector3D : public AlignedBase {
0029
0030 typedef Vector3D<Type> VecType;
0031
0032 private:
0033 Type vec[3];
0034
0035 public:
0036 using value_type = Type;
0037
0038 VECCORE_ATT_HOST_DEVICE
0039 VECGEOM_FORCE_INLINE
0040 Vector3D(const Type a, const Type b, const Type c)
0041 {
0042 vec[0] = a;
0043 vec[1] = b;
0044 vec[2] = c;
0045 }
0046
0047 VECCORE_ATT_HOST_DEVICE
0048 VECGEOM_FORCE_INLINE
0049 Vector3D()
0050 {
0051 vec[0] = 0;
0052 vec[1] = 0;
0053 vec[2] = 0;
0054 }
0055
0056 VECCORE_ATT_HOST_DEVICE
0057 VECGEOM_FORCE_INLINE
0058 Vector3D(const Type a)
0059 {
0060 vec[0] = a;
0061 vec[1] = a;
0062 vec[2] = a;
0063 }
0064
0065 template <typename TypeOther>
0066 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D(Vector3D<TypeOther> const &other)
0067 {
0068 vec[0] = other[0];
0069 vec[1] = other[1];
0070 vec[2] = other[2];
0071 }
0072
0073
0074
0075
0076
0077
0078 VECCORE_ATT_HOST
0079 Vector3D(std::string const &str)
0080 {
0081 int begin = 1, end = str.find(",");
0082 vec[0] = std::atof(str.substr(begin, end - begin).c_str());
0083 begin = end + 2;
0084 end = str.find(",", begin);
0085 vec[1] = std::atof(str.substr(begin, end - begin).c_str());
0086 begin = end + 2;
0087 end = str.find(")", begin);
0088 vec[2] = std::atof(str.substr(begin, end - begin).c_str());
0089 }
0090
0091
0092
0093
0094
0095 VECCORE_ATT_HOST_DEVICE
0096 VECGEOM_FORCE_INLINE
0097 Type &operator[](const int index) { return vec[index]; }
0098
0099
0100
0101
0102
0103 VECCORE_ATT_HOST_DEVICE
0104 VECGEOM_FORCE_INLINE
0105 Type const &operator[](const int index) const { return vec[index]; }
0106
0107 VECCORE_ATT_HOST_DEVICE
0108 VECGEOM_FORCE_INLINE
0109 Type &x() { return vec[0]; }
0110
0111 VECCORE_ATT_HOST_DEVICE
0112 VECGEOM_FORCE_INLINE
0113 Type const &x() const { return vec[0]; }
0114
0115 VECCORE_ATT_HOST_DEVICE
0116 VECGEOM_FORCE_INLINE
0117 Type &y() { return vec[1]; }
0118
0119 VECCORE_ATT_HOST_DEVICE
0120 VECGEOM_FORCE_INLINE
0121 Type const &y() const { return vec[1]; }
0122
0123 VECCORE_ATT_HOST_DEVICE
0124 VECGEOM_FORCE_INLINE
0125 Type &z() { return vec[2]; }
0126
0127 VECCORE_ATT_HOST_DEVICE
0128 VECGEOM_FORCE_INLINE
0129 Type const &z() const { return vec[2]; }
0130
0131
0132 VECCORE_ATT_HOST_DEVICE
0133 VECGEOM_FORCE_INLINE
0134 Vector2D<Type> XY() const { return {vec[0], vec[1]}; }
0135
0136 VECCORE_ATT_HOST_DEVICE
0137 VECGEOM_FORCE_INLINE
0138 Vector2D<Type> YX() const { return {vec[1], vec[0]}; }
0139
0140 VECCORE_ATT_HOST_DEVICE
0141 VECGEOM_FORCE_INLINE
0142 Vector2D<Type> XZ() const { return {vec[0], vec[2]}; }
0143
0144 VECCORE_ATT_HOST_DEVICE
0145 VECGEOM_FORCE_INLINE
0146 Vector2D<Type> ZX() const { return {vec[2], vec[0]}; }
0147
0148 VECCORE_ATT_HOST_DEVICE
0149 VECGEOM_FORCE_INLINE
0150 Vector2D<Type> YZ() const { return {vec[1], vec[2]}; }
0151
0152 VECCORE_ATT_HOST_DEVICE
0153 VECGEOM_FORCE_INLINE
0154 Vector2D<Type> ZY() const { return {vec[2], vec[1]}; }
0155
0156 VECCORE_ATT_HOST_DEVICE
0157 void Set(Type const &a, Type const &b, Type const &c)
0158 {
0159 vec[0] = a;
0160 vec[1] = b;
0161 vec[2] = c;
0162 }
0163
0164 VECCORE_ATT_HOST_DEVICE
0165 void Set(const Type a) { Set(a, a, a); }
0166
0167
0168 VECCORE_ATT_HOST_DEVICE
0169 VECGEOM_FORCE_INLINE
0170 Type Perp2() const { return vec[0] * vec[0] + vec[1] * vec[1]; }
0171
0172
0173 VECCORE_ATT_HOST_DEVICE
0174 VECGEOM_FORCE_INLINE
0175 Type Perp() const { return Sqrt(Perp2()); }
0176
0177
0178
0179 template <typename Type2>
0180 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Type Dot(Vector3D<Type> const &left, Vector3D<Type2> const &right)
0181 {
0182 return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
0183 }
0184
0185
0186
0187 template <typename Type2>
0188 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Type Dot(Vector3D<Type2> const &right) const
0189 {
0190 return Dot(*this, right);
0191 }
0192
0193
0194 VECCORE_ATT_HOST_DEVICE
0195 VECGEOM_FORCE_INLINE
0196 VecType MultiplyByComponents(VecType const &other) const { return *this * other; }
0197
0198
0199 VECCORE_ATT_HOST_DEVICE
0200 VECGEOM_FORCE_INLINE
0201 Type Mag2() const { return Dot(*this, *this); }
0202
0203
0204 VECCORE_ATT_HOST_DEVICE
0205 VECGEOM_FORCE_INLINE
0206 Type Mag() const { return Sqrt(Mag2()); }
0207
0208 VECCORE_ATT_HOST_DEVICE
0209 VECGEOM_FORCE_INLINE
0210 Type Length() const { return Mag(); }
0211
0212 VECCORE_ATT_HOST_DEVICE
0213 VECGEOM_FORCE_INLINE
0214 Type Length2() const { return Mag2(); }
0215
0216 VECCORE_ATT_HOST_DEVICE
0217 VECGEOM_FORCE_INLINE
0218 VecType Unit() const { return Type(1.) / Mag() * VecType(*this); }
0219
0220
0221
0222 VECCORE_ATT_HOST_DEVICE
0223 VECGEOM_FORCE_INLINE
0224 void Normalize() { *this *= (Type(1.) / Length()); }
0225
0226 VECCORE_ATT_HOST_DEVICE
0227 VECGEOM_FORCE_INLINE
0228 VecType Normalized() const { return Unit(); }
0229
0230
0231
0232 VECCORE_ATT_HOST_DEVICE
0233 VECGEOM_FORCE_INLINE
0234 bool IsNormalized() const
0235 {
0236
0237 Precision norm = Mag2();
0238 return Type(1.) - vecgeom::kTolerance < norm && norm < Type(1.) + vecgeom::kTolerance;
0239 }
0240
0241
0242 VECCORE_ATT_HOST_DEVICE
0243 VECGEOM_FORCE_INLINE
0244 Type Phi() const { return ATan2(vec[1], vec[0]); }
0245
0246
0247 VECCORE_ATT_HOST_DEVICE
0248 VECGEOM_FORCE_INLINE
0249 Type Theta() const { return ACos(vec[2] / Mag()); }
0250
0251
0252
0253 template <class FirstType, class SecondType>
0254 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Vector3D<Type> Cross(Vector3D<FirstType> const &left,
0255 Vector3D<SecondType> const &right)
0256 {
0257 return Vector3D<Type>(left[1] * right[2] - left[2] * right[1], left[2] * right[0] - left[0] * right[2],
0258 left[0] * right[1] - left[1] * right[0]);
0259 }
0260
0261
0262
0263 template <class OtherType>
0264 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> Cross(Vector3D<OtherType> const &right) const
0265 {
0266 return Cross<Type, OtherType>(*this, right);
0267 }
0268
0269
0270
0271 template <class FirstType, class SecondType>
0272 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Type CrossZ(Vector3D<FirstType> const &left,
0273 Vector3D<SecondType> const &right)
0274 {
0275 return left[0] * right[1] - left[1] * right[0];
0276 }
0277
0278
0279
0280 template <class OtherType>
0281 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Type CrossZ(Vector3D<OtherType> const &right) const
0282 {
0283 return CrossZ<Type, OtherType>(*this, right);
0284 }
0285
0286
0287
0288 VECCORE_ATT_HOST_DEVICE
0289 VECGEOM_FORCE_INLINE
0290 void Map(Type (*f)(const Type &))
0291 {
0292 vec[0] = f(vec[0]);
0293 vec[1] = f(vec[1]);
0294 vec[2] = f(vec[2]);
0295 }
0296
0297 VECCORE_ATT_HOST_DEVICE
0298 VECGEOM_FORCE_INLINE
0299 VecType Abs() const
0300 {
0301 return VecType(vecCore::math::Abs(vec[0]), vecCore::math::Abs(vec[1]), vecCore::math::Abs(vec[2]));
0302 }
0303
0304 template <typename BoolType>
0305 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void MaskedAssign(Vector3D<BoolType> const &condition,
0306 Vector3D<Type> const &value)
0307 {
0308 vec[0] = (condition[0]) ? value[0] : vec[0];
0309 vec[1] = (condition[1]) ? value[1] : vec[1];
0310 vec[2] = (condition[2]) ? value[2] : vec[2];
0311 }
0312
0313 VECCORE_ATT_HOST_DEVICE
0314 VECGEOM_FORCE_INLINE
0315 Type Min() const { return vecCore::math::Min(vec[0], vec[1], vec[2]); }
0316
0317 template <typename BoolVector>
0318 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Type MinSkip(BoolVector const &skip) const
0319 {
0320
0321 return (*this + kInfLength * Vector3D<Type>(skip[0], skip[1], skip[2])).Min();
0322 }
0323
0324 VECCORE_ATT_HOST_DEVICE
0325 VECGEOM_FORCE_INLINE
0326 Type Max() const { return vecCore::math::Max(vec[0], vec[1], vec[2]); }
0327
0328 template <typename BoolVector>
0329 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Type MaxSkip(BoolVector const &skip) const
0330 {
0331
0332 return (*this - kInfLength * Vector3D<Type>(skip[0], skip[1], skip[2])).Max();
0333 }
0334
0335 VECCORE_ATT_HOST_DEVICE
0336 VECGEOM_FORCE_INLINE
0337 static VecType FromCylindrical(Type r, Type phi, Type z) { return VecType(r * cos(phi), r * sin(phi), z); }
0338
0339 VECCORE_ATT_HOST_DEVICE
0340 VECGEOM_FORCE_INLINE
0341 VecType &FixZeroes()
0342 {
0343 using vecCore::math::Abs;
0344 for (int i = 0; i < 3; ++i) {
0345 vecCore::MaskedAssign(vec[i], Abs(vec[i]) < kTolerance, Type(0.0));
0346 }
0347 return *this;
0348 }
0349
0350
0351
0352 #define VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(OPERATOR) \
0353 VECCORE_ATT_HOST_DEVICE \
0354 VECGEOM_FORCE_INLINE \
0355 VecType &operator OPERATOR(const VecType & other) \
0356 { \
0357 vec[0] OPERATOR other.vec[0]; \
0358 vec[1] OPERATOR other.vec[1]; \
0359 vec[2] OPERATOR other.vec[2]; \
0360 return *this; \
0361 } \
0362 template <typename OtherType> \
0363 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE VecType &operator OPERATOR(const Vector3D<OtherType> &other) \
0364 { \
0365 vec[0] OPERATOR other[0]; \
0366 vec[1] OPERATOR other[1]; \
0367 vec[2] OPERATOR other[2]; \
0368 return *this; \
0369 } \
0370 VECCORE_ATT_HOST_DEVICE \
0371 VECGEOM_FORCE_INLINE \
0372 VecType &operator OPERATOR(const Type & scalar) \
0373 { \
0374 vec[0] OPERATOR scalar; \
0375 vec[1] OPERATOR scalar; \
0376 vec[2] OPERATOR scalar; \
0377 return *this; \
0378 }
0379 VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(+=)
0380 VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(-=)
0381 VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(*=)
0382 VECTOR3D_TEMPLATE_INPLACE_BINARY_OP(/=)
0383 #undef VECTOR3D_TEMPLATE_INPLACE_BINARY_OP
0384
0385 VECCORE_ATT_HOST_DEVICE
0386 VECGEOM_FORCE_INLINE
0387 operator bool() const { return vec[0] && vec[1] && vec[2]; }
0388 };
0389
0390 template <typename T>
0391 std::ostream &operator<<(std::ostream &os, Vector3D<T> const &vec)
0392 {
0393 os << "(" << vec[0] << ", " << vec[1] << ", " << vec[2] << ")";
0394 return os;
0395 }
0396
0397 #define VECTOR3D_BINARY_OP(OPERATOR, INPLACE) \
0398 template <typename Type, typename OtherType> \
0399 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator OPERATOR(const Vector3D<Type> &lhs, \
0400 const Vector3D<OtherType> &rhs) \
0401 { \
0402 Vector3D<Type> result(lhs); \
0403 result INPLACE rhs; \
0404 return result; \
0405 } \
0406 template <typename Type, typename ScalarType> \
0407 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator OPERATOR(Vector3D<Type> const &lhs, \
0408 const ScalarType rhs) \
0409 { \
0410 Vector3D<Type> result(lhs); \
0411 result INPLACE rhs; \
0412 return result; \
0413 } \
0414 template <typename Type, typename ScalarType> \
0415 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator OPERATOR(const ScalarType lhs, \
0416 Vector3D<Type> const &rhs) \
0417 { \
0418 Vector3D<Type> result(lhs); \
0419 result INPLACE rhs; \
0420 return result; \
0421 }
0422 VECTOR3D_BINARY_OP(+, +=)
0423 VECTOR3D_BINARY_OP(-, -=)
0424 VECTOR3D_BINARY_OP(*, *=)
0425 VECTOR3D_BINARY_OP(/, /=)
0426 #undef VECTOR3D_BINARY_OP
0427
0428 template <typename Type>
0429 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE bool operator==(Vector3D<Type> const &lhs, Vector3D<Type> const &rhs)
0430 {
0431 return Abs(lhs[0] - rhs[0]) < kToleranceDist<Type> && Abs(lhs[1] - rhs[1]) < kToleranceDist<Type> &&
0432 Abs(lhs[2] - rhs[2]) < kToleranceDist<Type>;
0433 }
0434
0435 template <typename Type>
0436 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE bool operator!=(Vector3D<Type> const &lhs, Vector3D<Type> const &rhs)
0437 {
0438 return !(lhs == rhs);
0439 }
0440
0441 template <typename Type>
0442 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator<(Vector3D<Type> const &lhs,
0443 Vector3D<Type> const &rhs)
0444 {
0445 return {lhs[0] < rhs[0], lhs[1] < rhs[1], lhs[2] < rhs[2]};
0446 }
0447
0448 template <typename Type>
0449 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator<=(Vector3D<Type> const &lhs,
0450 Vector3D<Type> const &rhs)
0451 {
0452 return {lhs[0] <= rhs[0], lhs[1] <= rhs[1], lhs[2] <= rhs[2]};
0453 }
0454
0455 template <typename Type>
0456 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator>(Vector3D<Type> const &lhs,
0457 Vector3D<Type> const &rhs)
0458 {
0459 return {lhs[0] > rhs[0], lhs[1] > rhs[1], lhs[2] > rhs[2]};
0460 }
0461
0462 template <typename Type>
0463 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<bool> operator>=(Vector3D<Type> const &lhs,
0464 Vector3D<Type> const &rhs)
0465 {
0466 return {lhs[0] >= rhs[0], lhs[1] >= rhs[1], lhs[2] >= rhs[2]};
0467 }
0468
0469 template <typename Type>
0470 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Type> operator-(Vector3D<Type> const &vec)
0471 {
0472 return Vector3D<Type>(-vec[0], -vec[1], -vec[2]);
0473 }
0474
0475 VECCORE_ATT_HOST_DEVICE
0476 VECGEOM_FORCE_INLINE
0477 Vector3D<bool> operator!(Vector3D<bool> const &vec) { return Vector3D<bool>(!vec[0], !vec[1], !vec[2]); }
0478
0479 #pragma GCC diagnostic push
0480 #pragma GCC diagnostic ignored "-Weffc++"
0481 #define VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP(OPERATOR) \
0482 VECCORE_ATT_HOST_DEVICE \
0483 VECGEOM_FORCE_INLINE \
0484 Vector3D<bool> operator OPERATOR(Vector3D<bool> const &lhs, Vector3D<bool> const &rhs) \
0485 { \
0486 return Vector3D<bool>(lhs[0] OPERATOR rhs[0], lhs[1] OPERATOR rhs[1], lhs[2] OPERATOR rhs[2]); \
0487 }
0488 VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP(&&)
0489 VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP(||)
0490 #undef VECTOR3D_SCALAR_BOOLEAN_LOGICAL_OP
0491 #pragma GCC diagnostic pop
0492 }
0493 }
0494
0495 namespace vecCore {
0496
0497 template <typename T>
0498 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void MaskedAssign(vecgeom::Vector3D<T> &v, const vecCore::Mask<T> &mask,
0499 const vecgeom::Vector3D<T> &val)
0500 {
0501 vecCore::MaskedAssign(v[0], mask, val[0]);
0502 vecCore::MaskedAssign(v[1], mask, val[1]);
0503 vecCore::MaskedAssign(v[2], mask, val[2]);
0504 }
0505
0506
0507
0508
0509
0510
0511 inline namespace math {
0512 template <typename T>
0513 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE vecgeom::Vector3D<T> Min(vecgeom::Vector3D<T> const &v1,
0514 vecgeom::Vector3D<T> const &v2)
0515 {
0516 vecgeom::Vector3D<T> result(vecCore::math::Min(v1.x(), v2.x()), vecCore::math::Min(v1.y(), v2.y()),
0517 vecCore::math::Min(v1.z(), v2.z()));
0518 return result;
0519 }
0520
0521
0522
0523
0524
0525
0526 template <typename T>
0527 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE vecgeom::Vector3D<T> Max(vecgeom::Vector3D<T> const &v1,
0528 vecgeom::Vector3D<T> const &v2)
0529 {
0530 vecgeom::Vector3D<T> result(vecCore::math::Max(v1.x(), v2.x()), vecCore::math::Max(v1.y(), v2.y()),
0531 vecCore::math::Max(v1.z(), v2.z()));
0532 return result;
0533 }
0534 }
0535 }
0536
0537
0538 using UVector3 = VECGEOM_NAMESPACE::Vector3D<double>;
0539
0540 #endif