Warning, file /include/orange/surf/detail/QuadricSphereConverter.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <optional>
0010
0011 #include "corecel/math/SoftEqual.hh"
0012
0013 #include "../Plane.hh"
0014 #include "../SimpleQuadric.hh"
0015
0016 namespace celeritas
0017 {
0018 namespace detail
0019 {
0020
0021
0022
0023
0024
0025
0026
0027 class QuadricSphereConverter
0028 {
0029 public:
0030
0031 inline QuadricSphereConverter(real_type tol);
0032
0033
0034 std::optional<Sphere> operator()(SimpleQuadric const& sq) const;
0035
0036 private:
0037 SoftEqual<> soft_equal_;
0038 };
0039
0040
0041
0042
0043
0044
0045
0046 QuadricSphereConverter::QuadricSphereConverter(real_type tol)
0047 : soft_equal_{tol}
0048 {
0049 }
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 std::optional<Sphere>
0075 QuadricSphereConverter::operator()(SimpleQuadric const& sq) const
0076 {
0077 CELER_EXPECT(std::all_of(
0078 sq.second().begin(), sq.second().end(), [this](real_type v) {
0079 return v >= 0 || soft_equal_(v, 0);
0080 }));
0081 constexpr auto X = to_int(Axis::x);
0082 constexpr auto Y = to_int(Axis::y);
0083 constexpr auto Z = to_int(Axis::z);
0084
0085 auto second = sq.second();
0086 if (!soft_equal_(second[X], second[Y])
0087 || !soft_equal_(second[X], second[Z]))
0088 {
0089
0090 return {};
0091 }
0092
0093 real_type const inv_norm = 3 / (second[0] + second[1] + second[2]);
0094 CELER_ASSERT(inv_norm > 0);
0095
0096 Real3 origin = make_array(sq.first());
0097 origin *= real_type{-0.5} * inv_norm;
0098
0099 real_type radius_sq = dot_product(origin, origin) - sq.zeroth() * inv_norm;
0100 if (radius_sq <= 0)
0101 {
0102
0103 return {};
0104 }
0105
0106
0107 origin += real_type{0};
0108 return Sphere::from_radius_sq(origin, radius_sq);
0109 }
0110
0111
0112 }
0113 }