File indexing completed on 2026-04-17 08:35:36
0001 #ifndef VECGEOM_ELLIPTICAL_IMPL_H
0002 #define VECGEOM_ELLIPTICAL_IMPL_H
0003
0004 #include <VecGeom/surfaces/surf/SurfaceHelper.h>
0005 #include <VecGeom/surfaces/base/Equations.h>
0006
0007 namespace vgbrep {
0008
0009 template <typename Real_t>
0010 struct SurfaceHelper<SurfaceType::kElliptical, Real_t> {
0011 EllipData<Real_t> const *fEllipData{nullptr};
0012
0013 VECGEOM_FORCE_INLINE
0014 VECCORE_ATT_HOST_DEVICE
0015 SurfaceHelper(EllipData<Real_t> const &ellipdata) { fEllipData = &ellipdata; }
0016
0017 VECGEOM_FORCE_INLINE
0018 VECCORE_ATT_HOST_DEVICE
0019
0020
0021
0022
0023 bool Inside(Vector3D<Real_t> const &point, bool flip, Real_t tol = vecgeom::kToleranceStrict<Real_t>)
0024 {
0025 int flipsign = !flip ? 1 : -1;
0026 return (point.x() * point.x() / fEllipData->fDDx + point.y() * point.y() / fEllipData->fDDy <
0027 static_cast<Real_t>(1) + flipsign * tol);
0028 }
0029
0030 VECGEOM_FORCE_INLINE
0031 VECCORE_ATT_HOST_DEVICE
0032
0033
0034
0035
0036
0037
0038 bool Intersect(Vector3D<Real_t> const &point, Vector3D<Real_t> const &dir, bool left_side, Real_t &distance,
0039 bool &two_solutions, Real_t &safety)
0040 {
0041
0042 distance = vecgeom::InfinityLength<Real_t>();
0043
0044 Vector3D<Real_t> pcur(point);
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054 Real_t px = pcur.x() * fEllipData->fSx;
0055 Real_t py = pcur.y() * fEllipData->fSy;
0056 Real_t vx = dir.x() * fEllipData->fSx;
0057 Real_t vy = dir.y() * fEllipData->fSy;
0058
0059
0060 Real_t rr = px * px + py * py;
0061 Real_t A = vx * vx + vy * vy;
0062 Real_t B = px * vx + py * vy;
0063 Real_t C = rr - fEllipData->R * fEllipData->R;
0064
0065 QuadraticCoef<Real_t> coef;
0066 coef.phalf = B / vecgeom::NonZero(A);
0067 coef.q = C / vecgeom::NonZero(A);
0068
0069 Real_t roots[2];
0070 int numroots;
0071 QuadraticSolver(coef, roots, numroots);
0072 two_solutions = (numroots == 2 && roots[0] > -vecgeom::kToleranceStrict<Real_t> &&
0073 roots[1] > -vecgeom::kToleranceStrict<Real_t>);
0074 for (auto i = 0; i < numroots; ++i) {
0075 distance = roots[i];
0076 Vector3D<Real_t> onsurf = point + distance * dir;
0077 Vector3D<Real_t> normal(onsurf[0] * fEllipData->fDDy, onsurf[1] * fEllipData->fDDx, 0);
0078 bool hit = left_side ^ (dir.Dot(normal) < 0);
0079
0080 if (hit) {
0081 if (distance < -vecgeom::kToleranceStrict<Real_t>) {
0082 Real_t x = point.x() * fEllipData->fSx;
0083 Real_t y = point.y() * fEllipData->fSy;
0084 Real_t rho = vecCore::math::Sqrt(x * x + y * y);
0085 safety = fEllipData->R - rho;
0086 }
0087 return true;
0088 }
0089 }
0090 return false;
0091 }
0092
0093 VECGEOM_FORCE_INLINE
0094 VECCORE_ATT_HOST_DEVICE
0095
0096
0097
0098
0099
0100
0101
0102 bool Safety(Vector3D<Real_t> const &point, bool left_side, Real_t &distance, Vector3D<Real_t> &onsurf) const
0103 {
0104 Real_t x = point.x() * fEllipData->fSx;
0105 Real_t y = point.y() * fEllipData->fSy;
0106 Real_t rho = vecCore::math::Sqrt(x * x + y * y);
0107 distance = left_side ? fEllipData->R - rho : rho - fEllipData->R;
0108 onsurf = point;
0109 return distance > -vecgeom::kToleranceDist<Real_t>;
0110 }
0111 };
0112
0113 }
0114
0115 #endif