Mantid
Loading...
Searching...
No Matches
MDImplicitFunction.h
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2011 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7#pragma once
8
12#include <algorithm>
13#include <memory>
14#include <string>
15#include <vector>
16
17namespace Mantid {
18namespace Geometry {
19
45class MANTID_GEOMETRY_DLL MDImplicitFunction {
46public:
48 virtual ~MDImplicitFunction() = default;
49
50 void addPlane(const MDPlane &plane);
51
54 const MDPlane &getPlane(size_t index) const { return m_planes[index]; }
55
57 size_t getNumDims() const { return m_nd; }
58
60 size_t getNumPlanes() const { return m_planes.size(); }
61
63 virtual std::string getName() const {
64 throw std::runtime_error("Cannot call MDImplicitFunction does not implement getName()");
65 }
66
68 virtual std::string toXMLString() const {
69 throw std::runtime_error("Cannot call MDImplicitFunction does not implement toXMLString()");
70 }
71
72 //----------------------------------------------------------------------------------------------
76 enum eContact {
78 NOT_TOUCHING = 0,
80 TOUCHING = 1,
82 CONTAINED = 2
83 };
84
85 // ==================== Methods that are inline for performance
86 // ================================
87 //----------------------------------------------------------------------------------------------
95 virtual bool isPointContained(const coord_t *coords) {
96 const auto it = std::find_if(m_planes.begin(), m_planes.end(),
97 [coords](const MDPlane &plane) { return !plane.isPointBounded(coords); });
98 return it == m_planes.end();
99 }
100
101 //----------------------------------------------------------------------------------------------
109 virtual bool isPointContained(const Mantid::Kernel::VMD &coords) {
110 const auto it = std::find_if(m_planes.begin(), m_planes.end(),
111 [coords](const MDPlane &plane) { return !plane.isPointBounded(coords); });
112 return it == m_planes.end();
113 }
114
115 //----------------------------------------------------------------------------------------------
123 virtual bool isPointContained(const std::vector<coord_t> &coords) {
124 const auto it = std::find_if(m_planes.begin(), m_planes.end(),
125 [coords](const MDPlane &plane) { return !plane.isPointBounded(coords); });
126 return it == m_planes.end();
127 }
128
129 //----------------------------------------------------------------------------------------------
156 bool isBoxTouching(const std::vector<std::vector<coord_t>> &vertexes) {
157 // As the description states, the first plane with NO points inside it
158 // means the box does NOT touch. So iterate by planes
159 for (size_t i = 0; i < m_numPlanes; i++) {
160 const bool anyBounded =
161 std::any_of(vertexes.cbegin(), vertexes.cend(),
162 [this, i](const std::vector<coord_t> &vertex) { return m_planes[i].isPointBounded(vertex); });
163 // Not a single point is in this plane
164 if (!anyBounded)
165 // That means the box CANNOT touch the implicit function
166 return false;
167 }
168
169 return true;
170 }
171
172 //----------------------------------------------------------------------------------------------
183 bool isBoxTouching(const coord_t *vertexes, const size_t numPoints) {
184 // As the description states, the first plane with NO points inside it
185 // means the box does NOT touch. So iterate by planes
186 for (size_t i = 0; i < m_numPlanes; i++) {
187 size_t numBounded = 0;
188 for (size_t j = 0; j < numPoints; j++) {
189 if (m_planes[i].isPointBounded(vertexes + j * m_nd)) {
190 numBounded++;
191 // No need to evaluate any more points.
192 break;
193 }
194 }
195 // Not a single point is in this plane
196 if (numBounded == 0)
197 // That means the box CANNOT touch the implicit function
198 return false;
199 }
200 return true;
201 }
202
203 //----------------------------------------------------------------------------------------------
217 eContact boxContact(const coord_t *vertexes, const size_t numPoints) const {
218 // For speed, we can stop looking when we know the box CANNOT be fully
219 // contained.
220 bool lookForFullyContained = true;
221
222 // As the description states, the first plane with NO points inside it
223 // means the box does NOT touch. So iterate by planes
224 for (size_t i = 0; i < m_numPlanes; i++) {
225 size_t numBounded = 0;
226 for (size_t j = 0; j < numPoints; j++) {
227 if (m_planes[i].isPointBounded(vertexes + j * m_nd)) {
228 numBounded++;
229 // No need to evaluate any more points, unless we look for fully
230 // contained
231 if (!lookForFullyContained)
232 break;
233 } else
234 // One of the vertexes is not contained by one of the planes.
235 // This means that the box CANNOT be fully contained.
236 lookForFullyContained = false;
237 }
238 // Not a single point is in this plane
239 if (numBounded == 0)
240 // That means the box CANNOT touch the implicit function
241 return NOT_TOUCHING;
242 // If all points were within this plane, then there is still a chance that
243 // the box is fully contained
244 if (numBounded != numPoints)
245 lookForFullyContained = false;
246 }
247 // If nothing said that the box might not be fully contained, then it is
248 // fully contained!
249 if (lookForFullyContained)
250 return CONTAINED;
251 else
252 return TOUCHING;
253 }
254
255protected:
257 size_t m_nd;
258
260 std::vector<MDPlane> m_planes;
261
264};
265
266using MDImplicitFunction_sptr = std::shared_ptr<MDImplicitFunction>;
267
268} // namespace Geometry
269} // namespace Mantid
std::map< DeltaEMode::Type, std::string > index
An "ImplicitFunction" defining a hyper-cuboid-shaped region in N dimensions.
eContact boxContact(const coord_t *vertexes, const size_t numPoints) const
Determine how a box (consisting of a number of vertexes) is in contact with the implicit function.
eContact
Enum for describing the contact between a box and an implicit function.
virtual bool isPointContained(const std::vector< coord_t > &coords)
Is a point in MDimensions contained by this ImplicitFunction? If the point is bounded by ALL planes c...
virtual bool isPointContained(const Mantid::Kernel::VMD &coords)
Is a point in MDimensions contained by this ImplicitFunction? If the point is bounded by ALL planes c...
size_t m_numPlanes
Cached number of planes (for a sligh speed-up)
virtual std::string getName() const
virtual bool isPointContained(const coord_t *coords)
Is a point in MDimensions contained by this ImplicitFunction? If the point is bounded by ALL planes c...
bool isBoxTouching(const std::vector< std::vector< coord_t > > &vertexes)
Is there a chance that the box defined by these vertexes touches the implicit function volume?
std::vector< MDPlane > m_planes
Vector of all the planes applying for this implict function.
size_t m_nd
number of dimensions for which this object can be applied
virtual std::string toXMLString() const
const MDPlane & getPlane(size_t index) const
bool isBoxTouching(const coord_t *vertexes, const size_t numPoints)
Same as isBoxTouching(vector), except that it takes a bare array of coordinates.
A generalized description of a N-dimensional hyperplane.
Definition MDPlane.h:41
std::shared_ptr< MDImplicitFunction > MDImplicitFunction_sptr
Helper class which provides the Collimation Length for SANS instruments.
float coord_t
Typedef for the data type to use for coordinate axes in MD objects such as MDBox, MDEventWorkspace,...
Definition MDTypes.h:27