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 <memory>
13#include <string>
14#include <vector>
15
16namespace Mantid {
17namespace Geometry {
18
44class MANTID_GEOMETRY_DLL MDImplicitFunction {
45public:
47 virtual ~MDImplicitFunction() = default;
48
49 void addPlane(const MDPlane &plane);
50
53 const MDPlane &getPlane(size_t index) const { return m_planes[index]; }
54
56 size_t getNumDims() const { return m_nd; }
57
59 size_t getNumPlanes() const { return m_planes.size(); }
60
62 virtual std::string getName() const {
63 throw std::runtime_error("Cannot call MDImplicitFunction does not implement getName()");
64 }
65
67 virtual std::string toXMLString() const {
68 throw std::runtime_error("Cannot call MDImplicitFunction does not implement toXMLString()");
69 }
70
71 //----------------------------------------------------------------------------------------------
75 enum eContact {
77 NOT_TOUCHING = 0,
79 TOUCHING = 1,
81 CONTAINED = 2
82 };
83
84 // ==================== Methods that are inline for performance
85 // ================================
86 //----------------------------------------------------------------------------------------------
94 virtual bool isPointContained(const coord_t *coords) {
95 for (size_t i = 0; i < m_numPlanes; i++) {
96 if (!m_planes[i].isPointBounded(coords))
97 return false;
98 }
99 return true;
100 }
101
102 //----------------------------------------------------------------------------------------------
110 virtual bool isPointContained(const Mantid::Kernel::VMD &coords) {
111 for (size_t i = 0; i < m_numPlanes; i++) {
112 if (!m_planes[i].isPointBounded(coords))
113 return false;
114 }
115 return true;
116 }
117
118 //----------------------------------------------------------------------------------------------
126 virtual bool isPointContained(const std::vector<coord_t> &coords) {
127 for (size_t i = 0; i < m_numPlanes; i++) {
128 if (!m_planes[i].isPointBounded(coords))
129 return false;
130 }
131 return true;
132 }
133
134 //----------------------------------------------------------------------------------------------
161 bool isBoxTouching(const std::vector<std::vector<coord_t>> &vertexes) {
162 size_t numPoints = vertexes.size();
163
164 // As the description states, the first plane with NO points inside it
165 // means the box does NOT touch. So iterate by planes
166 for (size_t i = 0; i < m_numPlanes; i++) {
167 size_t numBounded = 0;
168 for (size_t j = 0; j < numPoints; j++) {
169 if (m_planes[i].isPointBounded(vertexes[j])) {
170 numBounded++;
171 // No need to evaluate any more points.
172 break;
173 }
174 }
175 // Not a single point is in this plane
176 if (numBounded == 0)
177 // That means the box CANNOT touch the implicit function
178 return false;
179 }
180
181 return true;
182 }
183
184 //----------------------------------------------------------------------------------------------
195 bool isBoxTouching(const coord_t *vertexes, const size_t numPoints) {
196 // As the description states, the first plane with NO points inside it
197 // means the box does NOT touch. So iterate by planes
198 for (size_t i = 0; i < m_numPlanes; i++) {
199 size_t numBounded = 0;
200 for (size_t j = 0; j < numPoints; j++) {
201 if (m_planes[i].isPointBounded(vertexes + j * m_nd)) {
202 numBounded++;
203 // No need to evaluate any more points.
204 break;
205 }
206 }
207 // Not a single point is in this plane
208 if (numBounded == 0)
209 // That means the box CANNOT touch the implicit function
210 return false;
211 }
212 return true;
213 }
214
215 //----------------------------------------------------------------------------------------------
229 eContact boxContact(const coord_t *vertexes, const size_t numPoints) const {
230 // For speed, we can stop looking when we know the box CANNOT be fully
231 // contained.
232 bool lookForFullyContained = true;
233
234 // As the description states, the first plane with NO points inside it
235 // means the box does NOT touch. So iterate by planes
236 for (size_t i = 0; i < m_numPlanes; i++) {
237 size_t numBounded = 0;
238 for (size_t j = 0; j < numPoints; j++) {
239 if (m_planes[i].isPointBounded(vertexes + j * m_nd)) {
240 numBounded++;
241 // No need to evaluate any more points, unless we look for fully
242 // contained
243 if (!lookForFullyContained)
244 break;
245 } else
246 // One of the vertexes is not contained by one of the planes.
247 // This means that the box CANNOT be fully contained.
248 lookForFullyContained = false;
249 }
250 // Not a single point is in this plane
251 if (numBounded == 0)
252 // That means the box CANNOT touch the implicit function
253 return NOT_TOUCHING;
254 // If all points were within this plane, then there is still a chance that
255 // the box is fully contained
256 if (numBounded != numPoints)
257 lookForFullyContained = false;
258 }
259 // If nothing said that the box might not be fully contained, then it is
260 // fully contained!
261 if (lookForFullyContained)
262 return CONTAINED;
263 else
264 return TOUCHING;
265 }
266
267protected:
269 size_t m_nd;
270
272 std::vector<MDPlane> m_planes;
273
276};
277
278using MDImplicitFunction_sptr = std::shared_ptr<MDImplicitFunction>;
279
280} // namespace Geometry
281} // namespace Mantid
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
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