File indexing completed on 2025-01-18 09:59:35
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <cmath>
0011 #include <type_traits>
0012
0013 #include "corecel/Assert.hh"
0014 #include "corecel/Macros.hh"
0015 #include "corecel/Types.hh"
0016 #include "corecel/cont/Array.hh"
0017 #include "corecel/math/NumericLimits.hh"
0018
0019 #include "Types.hh"
0020
0021 namespace celeritas
0022 {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 template<class T = ::celeritas::real_type>
0042 class BoundingBox
0043 {
0044 public:
0045
0046
0047 using real_type = T;
0048 using Real3 = Array<real_type, 3>;
0049
0050
0051 public:
0052
0053 static inline CELER_FUNCTION BoundingBox from_infinite();
0054
0055
0056 static CELER_CONSTEXPR_FUNCTION BoundingBox
0057 from_unchecked(Real3 const& lower, Real3 const& upper);
0058
0059
0060 CELER_CONSTEXPR_FUNCTION BoundingBox();
0061
0062
0063 inline CELER_FUNCTION BoundingBox(Real3 const& lower, Real3 const& upper);
0064
0065
0066
0067
0068 CELER_CONSTEXPR_FUNCTION Real3 const& lower() const
0069 {
0070 return this->point(Bound::lo);
0071 }
0072
0073
0074 CELER_CONSTEXPR_FUNCTION Real3 const& upper() const
0075 {
0076 return this->point(Bound::hi);
0077 }
0078
0079
0080 CELER_CONSTEXPR_FUNCTION Real3 const& point(Bound b) const
0081 {
0082 return points_[to_int(b)];
0083 }
0084
0085
0086 CELER_CONSTEXPR_FUNCTION explicit operator bool() const;
0087
0088
0089
0090
0091 CELER_CONSTEXPR_FUNCTION void
0092 shrink(Bound bnd, Axis axis, real_type position);
0093
0094
0095 CELER_CONSTEXPR_FUNCTION void
0096 grow(Bound bnd, Axis axis, real_type position);
0097
0098
0099 CELER_CONSTEXPR_FUNCTION void grow(Axis axis, real_type position);
0100
0101 private:
0102 Array<Real3, 2> points_;
0103
0104
0105 CELER_CONSTEXPR_FUNCTION
0106 BoundingBox(std::true_type, Real3 const& lower, Real3 const& upper);
0107 };
0108
0109
0110
0111
0112
0113
0114 using BBox = BoundingBox<>;
0115
0116
0117
0118
0119
0120
0121
0122 template<class T>
0123 CELER_CONSTEXPR_FUNCTION bool
0124 operator==(BoundingBox<T> const& lhs, BoundingBox<T> const& rhs)
0125 {
0126 return lhs.lower() == rhs.lower() && lhs.upper() == rhs.upper();
0127 }
0128
0129
0130
0131
0132
0133 template<class T>
0134 CELER_CONSTEXPR_FUNCTION bool
0135 operator!=(BoundingBox<T> const& lhs, BoundingBox<T> const& rhs)
0136 {
0137 return !(lhs == rhs);
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147 template<class T, class U>
0148 CELER_CONSTEXPR_FUNCTION bool
0149 is_inside(BoundingBox<T> const& bbox, Array<U, 3> const& point)
0150 {
0151 return bbox.lower()[0] <= point[0] && point[0] <= bbox.upper()[0]
0152 && bbox.lower()[1] <= point[1] && point[1] <= bbox.upper()[1]
0153 && bbox.lower()[2] <= point[2] && point[2] <= bbox.upper()[2];
0154 }
0155
0156
0157
0158
0159
0160
0161
0162 template<class T>
0163 CELER_FUNCTION BoundingBox<T> BoundingBox<T>::from_infinite()
0164 {
0165 constexpr real_type inf = numeric_limits<real_type>::infinity();
0166 return {{-inf, -inf, -inf}, {inf, inf, inf}};
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176 template<class T>
0177 CELER_CONSTEXPR_FUNCTION BoundingBox<T>
0178 BoundingBox<T>::from_unchecked(Real3 const& lo, Real3 const& hi)
0179 {
0180 return BoundingBox<T>{std::true_type{}, lo, hi};
0181 }
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 template<class T>
0197 CELER_CONSTEXPR_FUNCTION BoundingBox<T>::BoundingBox()
0198 {
0199 constexpr real_type inf = numeric_limits<real_type>::infinity();
0200 points_[to_int(Bound::lo)] = {inf, inf, inf};
0201 points_[to_int(Bound::hi)] = {-inf, -inf, -inf};
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211 template<class T>
0212 CELER_FUNCTION BoundingBox<T>::BoundingBox(Real3 const& lo, Real3 const& hi)
0213 : points_{{lo, hi}}
0214 {
0215 if constexpr (CELERITAS_DEBUG)
0216 {
0217 for (auto ax : {Axis::x, Axis::y, Axis::z})
0218 {
0219 CELER_EXPECT(this->lower()[to_int(ax)]
0220 <= this->upper()[to_int(ax)]);
0221 }
0222 }
0223 CELER_ENSURE(*this);
0224 }
0225
0226
0227
0228
0229
0230 template<class T>
0231 CELER_CONSTEXPR_FUNCTION
0232 BoundingBox<T>::BoundingBox(std::true_type, Real3 const& lo, Real3 const& hi)
0233 : points_{{lo, hi}}
0234 {
0235 }
0236
0237
0238
0239
0240
0241 template<class T>
0242 CELER_CONSTEXPR_FUNCTION BoundingBox<T>::operator bool() const
0243 {
0244 return this->lower()[0] <= this->upper()[0]
0245 && this->lower()[1] <= this->upper()[1]
0246 && this->lower()[2] <= this->upper()[2];
0247 }
0248
0249
0250
0251
0252
0253
0254
0255
0256 template<class T>
0257 CELER_CONSTEXPR_FUNCTION void
0258 BoundingBox<T>::shrink(Bound bnd, Axis axis, real_type position)
0259 {
0260 real_type p = points_[to_int(bnd)][to_int(axis)];
0261 if (bnd == Bound::lo)
0262 {
0263 p = std::fmax(p, position);
0264 }
0265 else
0266 {
0267 p = std::fmin(p, position);
0268 }
0269 points_[to_int(bnd)][to_int(axis)] = p;
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279 template<class T>
0280 CELER_CONSTEXPR_FUNCTION void
0281 BoundingBox<T>::grow(Bound bnd, Axis axis, real_type position)
0282 {
0283 real_type p = points_[to_int(bnd)][to_int(axis)];
0284 if (bnd == Bound::lo)
0285 {
0286 p = std::fmin(p, position);
0287 }
0288 else
0289 {
0290 p = std::fmax(p, position);
0291 }
0292 points_[to_int(bnd)][to_int(axis)] = p;
0293 }
0294
0295
0296
0297
0298
0299
0300
0301
0302 template<class T>
0303 CELER_CONSTEXPR_FUNCTION void
0304 BoundingBox<T>::grow(Axis axis, real_type position)
0305 {
0306 this->grow(Bound::lo, axis, position);
0307 this->grow(Bound::hi, axis, position);
0308 }
0309
0310
0311 }