File indexing completed on 2025-01-18 10:05:57
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Macros.hh"
0011 #include "corecel/cont/Array.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/math/ArrayUtils.hh"
0014 #include "orange/OrangeTypes.hh"
0015
0016 namespace celeritas
0017 {
0018
0019 template<Axis T>
0020 class PlaneAligned;
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 class Plane
0031 {
0032 public:
0033
0034
0035 using Intersections = Array<real_type, 1>;
0036 using StorageSpan = Span<real_type const, 4>;
0037
0038
0039
0040
0041
0042 static CELER_CONSTEXPR_FUNCTION SurfaceType surface_type()
0043 {
0044 return SurfaceType::p;
0045 }
0046
0047
0048 static CELER_CONSTEXPR_FUNCTION bool simple_safety() { return true; }
0049
0050 public:
0051
0052
0053
0054 explicit inline CELER_FUNCTION Plane(Real3 const& n, Real3 const& p);
0055
0056
0057 explicit inline CELER_FUNCTION Plane(Real3 const& n, real_type d);
0058
0059
0060 template<class R>
0061 explicit inline CELER_FUNCTION Plane(Span<R, StorageSpan::extent>);
0062
0063
0064 template<Axis T>
0065 explicit Plane(PlaneAligned<T> const& other) noexcept;
0066
0067
0068
0069
0070 CELER_FUNCTION Real3 const& normal() const { return normal_; }
0071
0072
0073 CELER_FUNCTION real_type displacement() const { return d_; }
0074
0075
0076 CELER_FUNCTION StorageSpan data() const { return {&normal_[0], 4}; }
0077
0078
0079
0080
0081 inline CELER_FUNCTION SignedSense calc_sense(Real3 const& pos) const;
0082
0083
0084 inline CELER_FUNCTION Intersections calc_intersections(
0085 Real3 const& pos, Real3 const& dir, SurfaceState on_surface) const;
0086
0087
0088 inline CELER_FUNCTION Real3 calc_normal(Real3 const&) const;
0089
0090 private:
0091
0092 Real3 normal_;
0093
0094
0095 real_type d_;
0096 };
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 CELER_FUNCTION Plane::Plane(Real3 const& n, Real3 const& p)
0107 : Plane{n, dot_product(n, p)}
0108 {
0109 }
0110
0111
0112
0113
0114
0115 CELER_FUNCTION Plane::Plane(Real3 const& n, real_type d) : normal_{n}, d_{d}
0116 {
0117 CELER_EXPECT(is_soft_unit_vector(normal_));
0118 }
0119
0120
0121
0122
0123
0124 template<class R>
0125 CELER_FUNCTION Plane::Plane(Span<R, StorageSpan::extent> data)
0126 : normal_{data[0], data[1], data[2]}, d_{data[3]}
0127 {
0128 }
0129
0130
0131
0132
0133
0134 CELER_FUNCTION SignedSense Plane::calc_sense(Real3 const& pos) const
0135 {
0136 return real_to_sense(dot_product(normal_, pos) - d_);
0137 }
0138
0139
0140
0141
0142
0143 CELER_FUNCTION auto
0144 Plane::calc_intersections(Real3 const& pos,
0145 Real3 const& dir,
0146 SurfaceState on_surface) const -> Intersections
0147 {
0148 real_type const n_dir = dot_product(normal_, dir);
0149 if (on_surface == SurfaceState::off && n_dir != 0)
0150 {
0151 real_type const n_pos = dot_product(normal_, pos);
0152 real_type dist = (d_ - n_pos) / n_dir;
0153 if (dist > 0)
0154 {
0155 return {dist};
0156 }
0157 }
0158 return {no_intersection()};
0159 }
0160
0161
0162
0163
0164
0165 CELER_FORCEINLINE_FUNCTION Real3 Plane::calc_normal(Real3 const&) const
0166 {
0167 return normal_;
0168 }
0169
0170
0171 }