File indexing completed on 2026-09-13 09:28:15
0001
0002
0003
0004 #ifndef VECGEOM_BASE_VECTOR2D_H_
0005 #define VECGEOM_BASE_VECTOR2D_H_
0006
0007 #include "VecGeom/base/Global.h"
0008
0009 #include "VecGeom/backend/scalar/Backend.h"
0010 #include "VecGeom/base/AlignedBase.h"
0011
0012 #include <algorithm>
0013 #include <ostream>
0014
0015 namespace vecgeom {
0016
0017 VECGEOM_DEVICE_FORWARD_DECLARE(template <typename Type> class Vector2D;);
0018 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE(class, Vector2D, typename);
0019
0020 inline namespace VECGEOM_IMPL_NAMESPACE {
0021
0022 template <typename Type>
0023 class Vector2D : public AlignedBase {
0024
0025 private:
0026 Type vec[2];
0027
0028 typedef Vector2D<Type> VecType;
0029
0030 public:
0031 using value_type = Type;
0032
0033 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Vector2D()
0034 {
0035 vec[0] = 0;
0036 vec[1] = 0;
0037 }
0038
0039 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Vector2D(const Type x, const Type y)
0040 {
0041 vec[0] = x;
0042 vec[1] = y;
0043 }
0044
0045 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Vector2D(const Type a)
0046 {
0047 vec[0] = a;
0048 vec[1] = a;
0049 }
0050
0051 VECCORE_ATT_HOST_DEVICE
0052 Vector2D(Vector2D const &other)
0053 {
0054 vec[0] = other[0];
0055 vec[1] = other[1];
0056 }
0057
0058 template <typename Real_i>
0059 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Vector2D(const Vector2D<Real_i> &other)
0060 {
0061 vec[0] = static_cast<Type>(other.x());
0062 vec[1] = static_cast<Type>(other.y());
0063 }
0064
0065 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE VecType operator=(VecType const &other)
0066 {
0067 vec[0] = other.vec[0];
0068 vec[1] = other.vec[1];
0069 return *this;
0070 }
0071
0072 VECCORE_ATT_HOST_DEVICE
0073 VECGEOM_FORCE_INLINE
0074 Type &operator[](const int index) { return vec[index]; }
0075
0076 VECCORE_ATT_HOST_DEVICE
0077 VECGEOM_FORCE_INLINE
0078 Type operator[](const int index) const { return vec[index]; }
0079
0080 VECCORE_ATT_HOST_DEVICE
0081 VECGEOM_FORCE_INLINE
0082 Type &x() { return vec[0]; }
0083
0084 VECCORE_ATT_HOST_DEVICE
0085 VECGEOM_FORCE_INLINE
0086 Type x() const { return vec[0]; }
0087
0088 VECCORE_ATT_HOST_DEVICE
0089 VECGEOM_FORCE_INLINE
0090 Type &y() { return vec[1]; }
0091
0092 VECCORE_ATT_HOST_DEVICE
0093 VECGEOM_FORCE_INLINE
0094 Type y() const { return vec[1]; }
0095
0096 VECCORE_ATT_HOST_DEVICE
0097 VECGEOM_FORCE_INLINE
0098 void Set(const Type x, const Type y)
0099 {
0100 vec[0] = x;
0101 vec[1] = y;
0102 }
0103
0104 VECCORE_ATT_HOST_DEVICE
0105 VECGEOM_FORCE_INLINE
0106 void Set(const Type a)
0107 {
0108 vec[0] = a;
0109 vec[1] = a;
0110 }
0111
0112 VECCORE_ATT_HOST_DEVICE
0113 VECGEOM_FORCE_INLINE
0114 Vector2D<Type> Abs() const { return Vector2D<Type>(vecCore::math::Abs(vec[0]), vecCore::math::Abs(vec[1])); }
0115
0116 VECCORE_ATT_HOST_DEVICE
0117 VECGEOM_FORCE_INLINE
0118 Type Min() const { return vecCore::math::Min(vec[0], vec[1]); };
0119
0120 VECCORE_ATT_HOST_DEVICE
0121 VECGEOM_FORCE_INLINE
0122 Type Max() const { return vecCore::math::Max(vec[0], vec[1]); };
0123
0124 VECCORE_ATT_HOST_DEVICE
0125 VECGEOM_FORCE_INLINE
0126 Type CrossZ(VecType const &other) const { return vec[0] * other.vec[1] - vec[1] * other.vec[0]; }
0127
0128
0129
0130 template <typename Type2>
0131 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE static Type Dot(Vector2D<Type> const &left, Vector2D<Type2> const &right)
0132 {
0133 return left[0] * right[0] + left[1] * right[1];
0134 }
0135
0136
0137
0138 template <typename Type2>
0139 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Type Dot(Vector2D<Type2> const &right) const
0140 {
0141 return Dot(*this, right);
0142 }
0143
0144
0145 VECCORE_ATT_HOST_DEVICE
0146 VECGEOM_FORCE_INLINE
0147 Type Mag2() const { return Dot(*this, *this); }
0148
0149
0150 VECCORE_ATT_HOST_DEVICE
0151 VECGEOM_FORCE_INLINE
0152 Type Mag() const { return Sqrt(Mag2()); }
0153
0154 VECCORE_ATT_HOST_DEVICE
0155 VECGEOM_FORCE_INLINE
0156 Type Length2() const { return Mag2(); }
0157
0158 VECCORE_ATT_HOST_DEVICE
0159 VECGEOM_FORCE_INLINE
0160 Type Length() const { return Mag(); }
0161
0162 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Vector2D<Type> Unit() const
0163 {
0164 return Type(1.) / NonZero(Mag()) * VecType(*this);
0165 }
0166
0167 VECCORE_ATT_HOST_DEVICE
0168 VECGEOM_FORCE_INLINE
0169 void Normalize() { *this *= (Type(1.) / NonZero(Mag())); }
0170
0171 VECCORE_ATT_HOST_DEVICE
0172 VECGEOM_FORCE_INLINE
0173 Vector2D<Type> Normalized() const { return Unit(); }
0174
0175 VECCORE_ATT_HOST_DEVICE
0176 VECGEOM_FORCE_INLINE
0177 bool IsNormalized() const
0178 {
0179 Precision norm = Mag2();
0180 return Type(1.) - vecgeom::kTolerance < norm && norm < Type(1.) + vecgeom::kTolerance;
0181 }
0182
0183
0184 VECCORE_ATT_HOST_DEVICE
0185 VECGEOM_FORCE_INLINE
0186 Type Phi() const { return ATan2(vec[1], vec[0]); }
0187
0188 #define VECTOR2D_TEMPLATE_INPLACE_BINARY_OP(OPERATOR) \
0189 VECCORE_ATT_HOST_DEVICE \
0190 VECGEOM_FORCE_INLINE \
0191 VecType &operator OPERATOR(const VecType & other) \
0192 { \
0193 vec[0] OPERATOR other.vec[0]; \
0194 vec[1] OPERATOR other.vec[1]; \
0195 return *this; \
0196 } \
0197 VECCORE_ATT_HOST_DEVICE \
0198 VECGEOM_FORCE_INLINE \
0199 VecType &operator OPERATOR(const Type & scalar) \
0200 { \
0201 vec[0] OPERATOR scalar; \
0202 vec[1] OPERATOR scalar; \
0203 return *this; \
0204 }
0205 VECTOR2D_TEMPLATE_INPLACE_BINARY_OP(+=)
0206 VECTOR2D_TEMPLATE_INPLACE_BINARY_OP(-=)
0207 VECTOR2D_TEMPLATE_INPLACE_BINARY_OP(*=)
0208 VECTOR2D_TEMPLATE_INPLACE_BINARY_OP(/=)
0209 #undef VECTOR2D_TEMPLATE_INPLACE_BINARY_OP
0210 };
0211
0212 template <typename Type>
0213 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE bool operator==(Vector2D<Type> const &lhs, Vector2D<Type> const &rhs)
0214 {
0215 return lhs[0] == rhs[0] && lhs[1] == rhs[1];
0216 }
0217
0218 template <typename Type>
0219 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE bool operator!=(Vector2D<Type> const &lhs, Vector2D<Type> const &rhs)
0220 {
0221 return !(lhs == rhs);
0222 }
0223
0224 template <typename Type>
0225 std::ostream &operator<<(std::ostream &os, Vector2D<Type> const &vec)
0226 {
0227 os << "(" << vec[0] << ", " << vec[1] << ")";
0228 return os;
0229 }
0230
0231 #define VECTOR2D_BINARY_OP(OPERATOR, INPLACE) \
0232 template <typename Type> \
0233 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector2D<Type> operator OPERATOR(const Vector2D<Type> &lhs, \
0234 const Vector2D<Type> &rhs) \
0235 { \
0236 Vector2D<Type> result(lhs); \
0237 result INPLACE rhs; \
0238 return result; \
0239 } \
0240 template <typename Type, typename ScalarType> \
0241 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector2D<Type> operator OPERATOR(Vector2D<Type> const &lhs, \
0242 const ScalarType rhs) \
0243 { \
0244 Vector2D<Type> result(lhs); \
0245 result INPLACE rhs; \
0246 return result; \
0247 } \
0248 template <typename Type, typename ScalarType> \
0249 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector2D<Type> operator OPERATOR(const ScalarType rhs, \
0250 Vector2D<Type> const &lhs) \
0251 { \
0252 Vector2D<Type> result(rhs); \
0253 result INPLACE lhs; \
0254 return result; \
0255 }
0256 VECTOR2D_BINARY_OP(+, +=)
0257 VECTOR2D_BINARY_OP(-, -=)
0258 VECTOR2D_BINARY_OP(*, *=)
0259 VECTOR2D_BINARY_OP(/, /=)
0260 #undef VECTOR2D_BINARY_OP
0261
0262 }
0263 }
0264
0265 #endif