https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
OrientedBoundingBox Class Reference

Oriented bounding box in 2 D or 3 D. More...

#include <OrientedBoundingBox.h>

Public Member Functions

 OrientedBoundingBox ()
 Default-constructs an empty box (zero dimension, no axes).
 
 OrientedBoundingBox (const std::vector< std::pair< Point, Point > > &axis_pairs)
 Build the box from a set of axis end-points.
 
bool contains (const Point &pt, const Real tolerance=libMesh::TOLERANCE) const
 Test whether a point lies inside or on the box.
 
Point centroid () const
 
Point getAxisDirection (unsigned int i) const
 
Real getAxisLength (unsigned int i) const
 
Point getMinimalCorner () const
 
Point getMaximalCorner () const
 
void print (std::ostream &os) const
 Print a summary (dimension, origin, axes).
 
void writeMesh (const std::filesystem::path &path, const libMesh::Parallel::Communicator &comm) const
 Write the oriented box as a single libMesh element to a mesh file.
 
void writeRayAlongShortestAxis (const std::filesystem::path &ray_path, const libMesh::Parallel::Communicator &comm) const
 Write a single-EDGE2 mesh representing a "ray" emanating from the box.
 
Real getProjectedLength (const Point &pt, unsigned int i) const
 Get the length of the projection of a point onto axis i.
 

Private Attributes

Point _minimal_corner
 shared minimal corner
 
Point _maximal_corner
 shared maximal corner
 
std::vector< Point > _dirs
 orthonormal basis vectors (size = _dim)
 
std::vector< Real > _len
 length along each basis (size = _dim)
 
unsigned int _dim = 0u
 spatial dimension (2 or 3)
 

Detailed Description

Oriented bounding box in 2 D or 3 D.

An N-D (N = 2 or 3) oriented bounding box defined by one common origin, N orthonormal directions, and a length along each direction.

Construction is based on N "(min,max)" pairs that share a common min point:

Example (3-D): {{o, o+dx}, {o, o+dy}, {o, o+dz}}

The sequence of pairs is usually supplied in the order main axis, secondary axis, then minor axis (in other class).

Definition at line 44 of file OrientedBoundingBox.h.

Constructor & Destructor Documentation

◆ OrientedBoundingBox() [1/2]

OrientedBoundingBox::OrientedBoundingBox ( )
default

Default-constructs an empty box (zero dimension, no axes).

◆ OrientedBoundingBox() [2/2]

OrientedBoundingBox::OrientedBoundingBox ( const std::vector< std::pair< Point, Point > > &  axis_pairs)
explicit

Build the box from a set of axis end-points.

Each element in axis_pairs is a (origin, far-end) pair defining one axis. The first element's first point is taken as the shared origin. The vectors v_i = (axis_pairs[i].second - origin) are normalised to obtain an orthonormal basis; their norms become the edge lengths. If the supplied axes are not mutually orthogonal, construction fails with a run-time assertion.

Definition at line 26 of file OrientedBoundingBox.C.

27{
28 _dim = static_cast<unsigned int>(axis_pairs.size());
29 mooseAssert(_dim == 2 || _dim == 3, "OrientedBoundingBox requires 2 or 3 axis pairs");
30 _dirs.resize(_dim);
31 _len.resize(_dim);
32
33 _minimal_corner = axis_pairs[0].first;
34
36 // (a) Build orthonormal basis & lengths
37 for (const auto i : make_range(_dim))
38 {
39 const Point vec = axis_pairs[i].second - _minimal_corner;
40 _dirs[i] = vec.unit();
41 _len[i] = vec.norm();
42 _maximal_corner += _len[i] * _dirs[i];
43 }
44
45 // (b) Ensure orthogonality
46 for (const auto i : make_range(_dim))
47 for ([[maybe_unused]] const auto j : make_range(i + 1, _dim))
48 mooseAssert(MooseUtils::absoluteFuzzyEqual(_dirs[i] * _dirs[j], 0.0),
49 "Basis directions are not orthogonal");
50}
for(PetscInt i=0;i< nvars;++i)
std::vector< Real > _len
length along each basis (size = _dim)
Point _minimal_corner
shared minimal corner
unsigned int _dim
spatial dimension (2 or 3)
std::vector< Point > _dirs
orthonormal basis vectors (size = _dim)
Point _maximal_corner
shared maximal corner
IntRange< T > make_range(T beg, T end)

Member Function Documentation

◆ centroid()

Point OrientedBoundingBox::centroid ( ) const
Returns
Geometric centroid of the box.

Definition at line 75 of file OrientedBoundingBox.C.

76{
77 return 0.5 * (_minimal_corner + _maximal_corner);
78}

◆ contains()

bool OrientedBoundingBox::contains ( const Point &  pt,
const Real  tolerance = libMesh::TOLERANCE 
) const

Test whether a point lies inside or on the box.

Parameters
ptQuery point.
toleranceFuzzy tolerance applied along each axis (default: libMesh::TOLERANCE).
Returns
true if the point projection along every axis falls in the range [0, len_i] within the specified tolerance.

Definition at line 61 of file OrientedBoundingBox.C.

62{
63 const Point rel = pt - _minimal_corner;
64 for (const auto i : make_range(_dim))
65 {
66 const Real proj = rel * _dirs[i];
67 if (!MooseUtils::absoluteFuzzyGreaterEqual(proj, 0.0, tolerance) ||
68 !MooseUtils::absoluteFuzzyLessEqual(proj, _len[i], tolerance))
69 return false;
70 }
71 return true;
72}
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

Referenced by AdaptiveRayContainmentCheck::isOutsideBoundingBox().

◆ getAxisDirection()

Point OrientedBoundingBox::getAxisDirection ( unsigned int  i) const
Returns
Unit direction vector of axis i.

Definition at line 81 of file OrientedBoundingBox.C.

82{
83 mooseAssert(i < _dim, "Invalid axis index");
84 return _dirs[i];
85}

Referenced by AdaptiveRayContainmentCheck::sideness().

◆ getAxisLength()

Real OrientedBoundingBox::getAxisLength ( unsigned int  i) const
Returns
Length of axis i.

Definition at line 88 of file OrientedBoundingBox.C.

89{
90 mooseAssert(i < _dim, "Invalid axis index");
91 return _len[i];
92}

Referenced by AdaptiveRayContainmentCheck::rayStartOutsideOBB().

◆ getMaximalCorner()

Point OrientedBoundingBox::getMaximalCorner ( ) const
Returns
The shared maximal corner of the box.

Definition at line 109 of file OrientedBoundingBox.C.

110{
111 return _maximal_corner;
112}

Referenced by AdaptiveRayContainmentCheck::rayStartOutsideOBB().

◆ getMinimalCorner()

Point OrientedBoundingBox::getMinimalCorner ( ) const
Returns
The shared minimal corner of the box.

Definition at line 103 of file OrientedBoundingBox.C.

104{
105 return _minimal_corner;
106}

Referenced by AdaptiveRayContainmentCheck::rayStartOutsideOBB().

◆ getProjectedLength()

Real OrientedBoundingBox::getProjectedLength ( const Point &  pt,
unsigned int  i 
) const

Get the length of the projection of a point onto axis i.

This computes the length of the projection of the point pt onto the orthonormal basis vector dirs[i], relative to the minimal corner.

Parameters
ptQuery point.
iAxis index (0 for first, 1 for second, etc.).
Returns
Length of the projection along axis i.

Definition at line 95 of file OrientedBoundingBox.C.

96{
97 mooseAssert(i < _dim, "Invalid axis index");
98 const Point rel = pt - _minimal_corner;
99 return rel * _dirs[i];
100}

Referenced by AdaptiveRayContainmentCheck::rayStartOutsideOBB().

◆ print()

void OrientedBoundingBox::print ( std::ostream &  os) const

Print a summary (dimension, origin, axes).

Definition at line 53 of file OrientedBoundingBox.C.

54{
55 os << "OrientedBoundingBox: dim=" << _dim << ", origin=" << _minimal_corner << '\n';
56 for (const auto i : make_range(_dim))
57 os << " axis[" << i << "] dir=" << _dirs[i] << ", len=" << _len[i] << '\n';
58}

◆ writeMesh()

void OrientedBoundingBox::writeMesh ( const std::filesystem::path &  path,
const libMesh::Parallel::Communicator comm 
) const

Write the oriented box as a single libMesh element to a mesh file.

Builds one reference element (QUAD4 in 2-D, HEX8 in 3-D), maps its corners onto the oriented box, and delegates file output to libMesh's mesh writer. The output format is chosen from the file extension (use .e for ExodusII, which is always available). Writing is collective, so all ranks on comm must call it.

Parameters
pathOutput path; extension selects the libMesh writer.
commCommunicator the temporary mesh is built and written on.

Definition at line 115 of file OrientedBoundingBox.C.

117{
118 mooseAssert(_dim == 2 || _dim == 3, "writeMesh supports only 2D or 3D boxes.");
119
120 // Build a single reference element (unit square in 2D, unit cube in 3D) and let
121 // libMesh own the node ordering, connectivity, and output format.
123 if (_dim == 2)
125 else
127 mesh, 1, 1, 1, 0., 1., 0., 1., 0., 1., libMesh::HEX8);
128
129 // Map each reference corner onto the oriented box:
130 // x = origin + sum_axis r_axis * len_axis * dir_axis
131 for (auto * node : mesh.node_ptr_range())
132 {
133 const Point reference = *node;
134 Point mapped = _minimal_corner;
135 for (const auto axis : make_range(_dim))
136 mapped += reference(axis) * _len[axis] * _dirs[axis];
137 *node = mapped;
138 }
139
140 if (!path.parent_path().empty())
141 {
142 std::error_code ec;
143 fs::create_directories(path.parent_path(), ec);
144 }
145 mesh.write(path.string());
146}
MeshBase & mesh
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)

Referenced by AdaptiveRayContainmentCheck::buildObbKdtreeAndMaxProjectedDiagonal().

◆ writeRayAlongShortestAxis()

void OrientedBoundingBox::writeRayAlongShortestAxis ( const std::filesystem::path &  ray_path,
const libMesh::Parallel::Communicator comm 
) const

Write a single-EDGE2 mesh representing a "ray" emanating from the box.

(a) The ray originates at the centre of the face (2-D) or face-centre (3-D) orthogonal to the shortest axis. (b) It is aligned with that shortest axis and its length equals the corresponding edge length.

The output format is chosen from the file extension (use .e for ExodusII). Writing is collective, so all ranks on comm must call it.

Parameters
ray_pathOutput path; extension selects the libMesh writer.
commCommunicator the temporary mesh is built and written on.

Definition at line 149 of file OrientedBoundingBox.C.

151{
152 mooseAssert(_dim == 2 || _dim == 3, "Ray writing only supports 2D or 3D");
153
154 unsigned int i_min = 0;
155 for (const auto i : make_range(1u, _dim))
156 if (_len[i] < _len[i_min])
157 i_min = i;
158
159 Point start = _minimal_corner;
160 for (const auto i : make_range(_dim))
161 if (i != i_min)
162 start += 0.5 * _len[i] * _dirs[i];
163
164 const Point end = start + _len[i_min] * _dirs[i_min];
165
166 // A single EDGE2 spanning the ray; libMesh owns the output format.
168 libMesh::Node * n0 = mesh.add_point(start, 0);
169 libMesh::Node * n1 = mesh.add_point(end, 1);
171 edge->set_node(0, n0);
172 edge->set_node(1, n1);
173 mesh.add_elem(std::move(edge));
174 mesh.prepare_for_use();
175
176 if (!ray_path.parent_path().empty())
177 {
178 std::error_code ec;
179 fs::create_directories(ray_path.parent_path(), ec);
180 }
181 mesh.write(ray_path.string());
182}
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)

Referenced by AdaptiveRayContainmentCheck::buildObbKdtreeAndMaxProjectedDiagonal().

Member Data Documentation

◆ _dim

unsigned int OrientedBoundingBox::_dim = 0u
private

◆ _dirs

std::vector<Point> OrientedBoundingBox::_dirs
private

orthonormal basis vectors (size = _dim)

Definition at line 143 of file OrientedBoundingBox.h.

Referenced by contains(), getAxisDirection(), getProjectedLength(), OrientedBoundingBox(), print(), writeMesh(), and writeRayAlongShortestAxis().

◆ _len

std::vector<Real> OrientedBoundingBox::_len
private

length along each basis (size = _dim)

Definition at line 144 of file OrientedBoundingBox.h.

Referenced by contains(), getAxisLength(), OrientedBoundingBox(), print(), writeMesh(), and writeRayAlongShortestAxis().

◆ _maximal_corner

Point OrientedBoundingBox::_maximal_corner
private

shared maximal corner

Definition at line 142 of file OrientedBoundingBox.h.

Referenced by centroid(), getMaximalCorner(), and OrientedBoundingBox().

◆ _minimal_corner

Point OrientedBoundingBox::_minimal_corner
private

The documentation for this class was generated from the following files: