File indexing completed on 2026-04-17 08:35:36
0001 #ifndef VECGEOM_CONICAL_IMPL_H
0002 #define VECGEOM_CONICAL_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::kConical, Real_t> {
0011
0012 VECGEOM_FORCE_INLINE
0013 VECCORE_ATT_HOST_DEVICE
0014 SurfaceHelper() {}
0015
0016 VECGEOM_FORCE_INLINE
0017 VECCORE_ATT_HOST_DEVICE
0018
0019
0020
0021
0022 bool Inside(Vector3D<Real_t> const &point, bool flip, Real_t radius, Real_t slope,
0023 Real_t tol = vecgeom::kToleranceStrict<Real_t>)
0024 {
0025 int flipsign = (radius < 0) ? -1 : 1;
0026 int bool_flipsign = !flip ? 1 : -1;
0027 Real_t coneR = Abs(radius) + point.z() * slope;
0028 Real_t rho = point.Perp();
0029 return flipsign * (rho - coneR) < bool_flipsign * tol;
0030 }
0031
0032 VECGEOM_FORCE_INLINE
0033 VECCORE_ATT_HOST_DEVICE
0034
0035
0036
0037
0038
0039
0040 bool Intersect(Vector3D<Real_t> const &point, Vector3D<Real_t> const &dir, bool left_side, Real_t &distance,
0041 bool &two_solutions, Real_t &safety, Real_t radius, Real_t slope)
0042 {
0043 QuadraticCoef<Real_t> coef;
0044 Real_t roots[2];
0045 int numroots = 0;
0046 bool flip_exiting = left_side ^ (radius < 0);
0047 ConeEq<Real_t>(point, dir, Abs(radius), slope, coef);
0048 QuadraticSolver(coef, roots, numroots);
0049 two_solutions = (numroots == 2 && roots[0] > -vecgeom::kToleranceStrict<Real_t> &&
0050 roots[1] > -vecgeom::kToleranceStrict<Real_t>);
0051 for (auto i = 0; i < numroots; ++i) {
0052 distance = roots[i];
0053 Vector3D<Real_t> onsurf = point + distance * dir;
0054
0055 if (Abs(radius) + onsurf[2] * slope < 0) continue;
0056 Vector3D<Real_t> normal(onsurf[0], onsurf[1], -std::sqrt(onsurf[0] * onsurf[0] + onsurf[1] * onsurf[1]) * slope);
0057 bool hit = flip_exiting ^ (dir.Dot(normal) < 0);
0058
0059 if (hit) {
0060 if (distance < -vecgeom::kToleranceStrict<Real_t>) {
0061 Real_t rho = point.Perp();
0062 auto distanceR = Abs(radius) + point[2] * slope - rho;
0063 Real_t calf = static_cast<Real_t>(1) / std::sqrt(static_cast<Real_t>(1) + slope * slope);
0064 safety = distanceR * calf;
0065 }
0066 return true;
0067 }
0068 }
0069 return false;
0070 }
0071
0072 VECGEOM_FORCE_INLINE
0073 VECCORE_ATT_HOST_DEVICE
0074
0075
0076
0077
0078
0079
0080 bool Safety(Vector3D<Real_t> const &point, bool left_side, Real_t &distance, Vector3D<Real_t> &onsurf, Real_t radius,
0081 Real_t slope) const
0082 {
0083 Real_t coneR = Abs(radius) + point[2] * slope;
0084 Real_t rho = point.Perp();
0085 bool flip_exiting = left_side ^ (radius < 0);
0086 auto distanceR = flip_exiting ? coneR - rho : rho - coneR;
0087 Real_t calf = static_cast<Real_t>(1) / std::sqrt(static_cast<Real_t>(1) + slope * slope);
0088 distance = distanceR * calf;
0089
0090 onsurf = point;
0091 onsurf[2] += distance * slope * calf;
0092 return distance > -vecgeom::kToleranceDist<Real_t>;
0093 }
0094 };
0095
0096 }
0097
0098 #endif