File indexing completed on 2026-09-10 09:29:07
0001
0002
0003
0004 #ifndef VECGEOM_BASE_SCALE3D_H_
0005 #define VECGEOM_BASE_SCALE3D_H_
0006
0007 #include "VecGeom/base/Assert.h"
0008 #include "VecGeom/base/Cuda.h"
0009 #include "VecGeom/base/Global.h"
0010
0011 #include "VecGeom/base/Vector3D.h"
0012 #ifdef VECGEOM_CUDA_INTERFACE
0013 #include "VecGeom/backend/cuda/Interface.h"
0014 #endif
0015
0016 #include <algorithm>
0017 #include <cmath>
0018 #include <cstring>
0019
0020 namespace vecgeom {
0021
0022 VECGEOM_DEVICE_FORWARD_DECLARE(class Scale3D;);
0023
0024 inline namespace VECGEOM_IMPL_NAMESPACE {
0025
0026 #ifndef VECCORE_CUDA
0027 }
0028 namespace cuda {
0029 class Scale3D;
0030 }
0031 inline namespace VECGEOM_IMPL_NAMESPACE {
0032
0033 #endif
0034
0035 class Scale3D {
0036
0037 private:
0038 Vector3D<Precision> fScale;
0039 Vector3D<Precision> fInvScale;
0040 Precision fSclLocal;
0041 Precision fSclMaster;
0042
0043 public:
0044
0045
0046
0047 VECCORE_ATT_HOST_DEVICE
0048 Scale3D() : fScale(1., 1., 1.), fInvScale(1., 1., 1.), fSclLocal(1.), fSclMaster(1.) {}
0049
0050
0051
0052
0053
0054
0055
0056 VECCORE_ATT_HOST_DEVICE
0057 Scale3D(Precision sx, Precision sy, Precision sz) : fScale(sx, sy, sz), fInvScale(), fSclLocal(1.), fSclMaster(1.)
0058 {
0059 Update();
0060 }
0061
0062
0063
0064
0065
0066 VECCORE_ATT_HOST_DEVICE
0067 Scale3D(Vector3D<Precision> const &scale) : fScale(scale), fInvScale(), fSclLocal(1.), fSclMaster(1.) { Update(); }
0068
0069
0070
0071
0072 VECCORE_ATT_HOST_DEVICE
0073 Scale3D(Scale3D const &other)
0074 : fScale(other.fScale), fInvScale(other.fInvScale), fSclLocal(other.fSclLocal), fSclMaster(other.fSclMaster)
0075 {
0076 }
0077
0078
0079
0080
0081 VECCORE_ATT_HOST_DEVICE
0082 Scale3D &operator=(Scale3D const &other)
0083 {
0084 fScale = other.fScale;
0085 fInvScale = other.fInvScale;
0086 fSclLocal = other.fSclLocal;
0087 fSclMaster = other.fSclMaster;
0088 return *this;
0089 }
0090
0091
0092
0093
0094
0095 VECCORE_ATT_HOST_DEVICE
0096 VECGEOM_FORCE_INLINE
0097 void Update()
0098 {
0099 VECGEOM_ASSERT(((fScale[0] != 0) && (fScale[1] != 0) && (fScale[2] != 0)));
0100 fInvScale.Set(1. / fScale[0], 1. / fScale[1], 1. / fScale[2]);
0101
0102 fSclLocal = Min(Abs(fInvScale[0]), Abs(fInvScale[1]));
0103 fSclLocal = Min(fSclLocal, Abs(fInvScale[2]));
0104 fSclMaster = Min(Abs(fScale[0]), Abs(fScale[1]));
0105 fSclMaster = Min(fSclMaster, Abs(fScale[2]));
0106 }
0107
0108
0109
0110
0111 VECCORE_ATT_HOST_DEVICE
0112 VECGEOM_FORCE_INLINE
0113 const Vector3D<Precision> &Scale() const { return fScale; }
0114
0115
0116
0117
0118 VECCORE_ATT_HOST_DEVICE
0119 VECGEOM_FORCE_INLINE
0120 const Vector3D<Precision> &InvScale() const { return fInvScale; }
0121
0122
0123
0124
0125 VECCORE_ATT_HOST_DEVICE
0126 VECGEOM_FORCE_INLINE
0127 void SetScale(Vector3D<Precision> const &scale)
0128 {
0129 fScale = scale;
0130 Update();
0131 }
0132
0133
0134
0135
0136 VECCORE_ATT_HOST_DEVICE
0137 VECGEOM_FORCE_INLINE
0138 void SetScale(Precision sx, Precision sy, Precision sz)
0139 {
0140 fScale.Set(sx, sy, sz);
0141 Update();
0142 }
0143
0144
0145
0146
0147 template <typename InputType>
0148 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transform(Vector3D<InputType> const &master,
0149 Vector3D<InputType> &local) const
0150 {
0151 local.Set(master[0] * fInvScale[0], master[1] * fInvScale[1], master[2] * fInvScale[2]);
0152 }
0153
0154 template <typename InputType>
0155 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<InputType> Transform(Vector3D<InputType> const &master) const
0156 {
0157 Vector3D<InputType> local(master[0] * fInvScale[0], master[1] * fInvScale[1], master[2] * fInvScale[2]);
0158 return local;
0159 }
0160
0161
0162
0163
0164 template <typename InputType>
0165 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void InverseTransform(Vector3D<InputType> const &local,
0166 Vector3D<InputType> &master) const
0167 {
0168 master.Set(local[0] * fScale[0], local[1] * fScale[1], local[2] * fScale[2]);
0169 }
0170
0171 template <typename InputType>
0172 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<InputType> InverseTransform(
0173 Vector3D<InputType> const &local) const
0174 {
0175 Vector3D<InputType> master(local[0] * fScale[0], local[1] * fScale[1], local[2] * fScale[2]);
0176 return master;
0177 }
0178
0179
0180
0181
0182 template <typename InputType>
0183 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void TransformNormal(Vector3D<InputType> const &master,
0184 Vector3D<InputType> &local) const
0185 {
0186 local.Set(master[0] * fInvScale[0], master[1] * fInvScale[1], master[2] * fInvScale[2]);
0187 local.Normalize();
0188 }
0189
0190 template <typename InputType>
0191 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<InputType> TransformNormal(
0192 Vector3D<InputType> const &master) const
0193 {
0194 Vector3D<InputType> local(master[0] * fInvScale[0], master[1] * fInvScale[1], master[2] * fInvScale[2]);
0195 local.Normalize();
0196 return local;
0197 }
0198
0199
0200
0201
0202 template <typename InputType>
0203 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void InverseTransformNormal(Vector3D<InputType> const &local,
0204 Vector3D<InputType> &master) const
0205 {
0206 master.Set(local[0] * fScale[0], local[1] * fScale[1], local[2] * fScale[2]);
0207 master.Normalize();
0208 }
0209
0210 template <typename InputType>
0211 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<InputType> InverseTransformNormal(
0212 Vector3D<InputType> const &local) const
0213 {
0214 Vector3D<InputType> master(local[0] * fScale[0], local[1] * fScale[1], local[2] * fScale[2]);
0215 master.Normalize();
0216 return master;
0217 }
0218
0219
0220
0221
0222 template <typename InputType>
0223 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE InputType TransformDistance(InputType const &dist,
0224 Vector3D<InputType> const &dir) const
0225 {
0226 Vector3D<InputType> v = dir * fInvScale;
0227 InputType scale = Sqrt(Vector3D<InputType>::Dot(v, v));
0228 return (scale * dist);
0229 }
0230
0231
0232
0233
0234 template <typename InputType>
0235 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE InputType TransformSafety(InputType safety) const
0236 {
0237 return (safety * fSclLocal);
0238 }
0239
0240
0241
0242
0243 template <typename InputType>
0244 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE InputType InverseTransformDistance(InputType const &dist,
0245 Vector3D<InputType> const &dir) const
0246 {
0247 Vector3D<InputType> v = dir * fScale;
0248 InputType scale = Sqrt(Vector3D<InputType>::Dot(v, v));
0249 return (scale * dist);
0250 }
0251
0252
0253
0254
0255 template <typename InputType>
0256 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE InputType InverseTransformSafety(InputType safety) const
0257 {
0258 return (safety * fSclMaster);
0259 }
0260
0261 public:
0262 static const Scale3D kIdentity;
0263
0264 };
0265
0266 std::ostream &operator<<(std::ostream &os, Scale3D const &scale);
0267 }
0268 }
0269
0270 #endif