Commit 868724e1 authored by Timo Koch's avatar Timo Koch
Browse files

[doc] Improve AABB tree / geometry collision docstrings

parent 7896d9fc
......@@ -16,9 +16,9 @@
*****************************************************************************/
/*!
* \file
* \brief A bounding box tree for grid point intersections
* \brief An axis-aligned bounding box volume hierarchy for dune grids
*
* Dumux implementation of the bounding box tree
* Dumux implementation of an AABB tree
* adapted from implementation in FEniCS by Anders Logg
*/
#ifndef DUMUX_BOUNDINGBOXTREE_HH
......@@ -34,10 +34,13 @@
namespace Dumux {
// optimized dimension-dependent methods
/*!
* \brief A helper class to optimize dimension-dependent methods
*/
template <int dimworld>
class BoundingBoxTreeHelper {};
//! Helper methods for world dimension three
template <>
class BoundingBoxTreeHelper<3>
{
......@@ -46,7 +49,7 @@ class BoundingBoxTreeHelper<3>
typedef Dune::FieldVector<double, 3> GlobalPosition;
public:
// Check whether a point is inside a given geometry
//! Check whether a point is inside a given three-dimensional geometry
template <class Geometry>
static typename std::enable_if<Geometry::mydimension == 3, bool>::type
pointInGeometry(const Geometry& geometry, const GlobalPosition& point)
......@@ -144,6 +147,7 @@ public:
<< type << " in three-dimensional world.");
}
//! Check whether a point is inside a given two-dimensional geometry
template <class Geometry>
static typename std::enable_if<Geometry::mydimension == 2, bool>::type
pointInGeometry(const Geometry& geometry, const GlobalPosition& point)
......@@ -181,6 +185,7 @@ public:
}
//! Check whether a point is inside a given one-dimensional geometry
template <class Geometry>
static typename std::enable_if<Geometry::mydimension == 1, bool>::type
pointInGeometry(const Geometry& geometry, const GlobalPosition& point)
......@@ -190,7 +195,7 @@ public:
point);
}
//! find out if a point is inside a tetrahedron
//! Find out whether a point is inside a tetrahedron (p0, p1, p2, p3)
static bool pointInTetrahedron(const GlobalPosition& p0, const GlobalPosition& p1,
const GlobalPosition& p2, const GlobalPosition& p3,
const GlobalPosition& point)
......@@ -225,7 +230,7 @@ public:
return true;
}
//! find out if a point is inside a triangle
//! Find out whether a point is inside a triangle (p0, p1, p2)
static bool pointInTriangle(const GlobalPosition& p0, const GlobalPosition& p1,
const GlobalPosition& p2, const GlobalPosition& point)
{
......@@ -266,7 +271,7 @@ public:
return true;
}
//! find out if a point is inside an interval
//! Find out whether a point is inside an interval (p0, p1)
static bool pointInInterval(const GlobalPosition& p0, const GlobalPosition& p1,
const GlobalPosition& point)
{
......@@ -301,8 +306,11 @@ public:
return false;
}
// Check whether a point is in a bounding box
// \param b point to bounding box coordinates
/*!
* \brief Check whether a point is in a bounding box
* \param point The point
* \param b Pointer to bounding box coordinates
*/
static bool pointInBoundingBox(const Dune::FieldVector<double, 3>& point,
const double* b)
{
......@@ -314,8 +322,10 @@ public:
b[2] - eps2 <= point[2] && point[2] <= b[5] + eps2);
}
// Check whether bounding box (a - pointer to bounding box coordinates)
// collides with bounding box (b - pointer to bounding box coordinates)
/*!
* \brief Check whether bounding box a collides with bounding box b
* \param a, b Pointer to bounding box coordinates
*/
static bool boundingBoxInBoundingBox(const double* a,
const double* b)
{
......@@ -327,7 +337,7 @@ public:
b[2] - eps2 <= a[5] && a[2] <= b[5] + eps2);
}
// Compute the bounding box of a vector of bounding boxes
//! Compute the bounding box of a vector of bounding boxes
static void computeBBoxOfBBoxes(double* bBox,
std::size_t& axis,
const std::vector<double>& leafBoxes,
......@@ -366,7 +376,7 @@ public:
axis = 2;
}
// Sort the bounding boxes along the longest axis
//! Sort the bounding boxes along the longest axis
static void sortBoundingBoxes(std::size_t axis,
const std::vector<double>& leafBoxes,
const std::vector<unsigned int>::iterator& begin,
......@@ -384,8 +394,10 @@ public:
}
}
// Comparison operators for sorting bounding boxes. There are sorted by their
// mid points along the longest axis
/*!
* \brief Comparison function for sorting bounding boxes on the x-axis
* \note This could be replaced by lambdas
*/
struct lessXBox
{
const std::vector<double>& bBoxes;
......@@ -398,6 +410,10 @@ public:
}
};
/*!
* \brief Comparison function for sorting bounding boxes on the y-axis
* \note This could be replaced by lambdas
*/
struct lessYBox
{
const std::vector<double>& bBoxes;
......@@ -410,6 +426,10 @@ public:
}
};
/*!
* \brief Comparison function for sorting bounding boxes on the z-axis
* \note This could be replaced by lambdas
*/
struct lessZBox
{
const std::vector<double>& bBoxes;
......@@ -423,6 +443,7 @@ public:
};
};
//! Helper methods for world dimension two
template <>
class BoundingBoxTreeHelper<2>
{
......@@ -531,8 +552,11 @@ public:
return false;
}
// Check whether a point is in a bounding box
// \param b point to bounding box coordinates
/*!
* \brief Check whether a point is in a bounding box
* \param point The point
* \param b Pointer to bounding box coordinates
*/
static bool pointInBoundingBox(const Dune::FieldVector<double, 2>& point,
const double* b)
{
......@@ -542,8 +566,10 @@ public:
b[1] - eps1 <= point[1] && point[1] <= b[3] + eps1);
}
// Check whether bounding box (a - pointer to bounding box coordinates)
// collides with bounding box (b - pointer to bounding box coordinates)
/*!
* \brief Check whether bounding box a collides with bounding box b
* \param a, b Pointer to bounding box coordinates
*/
static bool boundingBoxInBoundingBox(const double* a,
const double* b)
{
......@@ -553,7 +579,7 @@ public:
b[1] - eps1 <= a[3] && a[1] <= b[3] + eps1);
}
// Compute the bounding box of a vector of bounding boxes
//! Compute the bounding box of a vector of bounding boxes
static void computeBBoxOfBBoxes(double* bBox,
std::size_t& axis,
const std::vector<double>& leafBoxes,
......@@ -587,7 +613,7 @@ public:
axis = 1;
}
// Sort the bounding boxes along the longest axis
//! Sort the bounding boxes along the longest axis
static void sortBoundingBoxes(std::size_t axis,
const std::vector<double>& leafBoxes,
const std::vector<unsigned int>::iterator& begin,
......@@ -600,8 +626,10 @@ public:
std::nth_element(begin, middle, end, lessYBox(leafBoxes));
}
// Comparison operators for sorting bounding boxes. There are sorted by their
// mid points along the longest axis
/*!
* \brief Comparison function for sorting bounding boxes on the x-axis
* \note This could be replaced by lambdas
*/
struct lessXBox
{
const std::vector<double>& bBoxes;
......@@ -614,6 +642,10 @@ public:
}
};
/*!
* \brief Comparison function for sorting bounding boxes on the y-axis
* \note This could be replaced by lambdas
*/
struct lessYBox
{
const std::vector<double>& bBoxes;
......@@ -627,6 +659,7 @@ public:
};
};
//! Helper methods for world dimension one
template <>
class BoundingBoxTreeHelper<1>
{
......@@ -668,8 +701,11 @@ public:
return false;
}
// Check whether a point is in a bounding box
// \param b point to bounding box coordinates
/*!
* \brief Check whether a point is in a bounding box
* \param point The point
* \param b Pointer to bounding box coordinates
*/
static bool pointInBoundingBox(const GlobalPosition& point,
const double* b)
{
......@@ -677,8 +713,10 @@ public:
return b[0] - eps0 <= point[0] && point[0] <= b[1] + eps0;
}
// Check whether bounding box (a - pointer to bounding box coordinates)
// collides with bounding box (b - pointer to bounding box coordinates)
/*!
* \brief Check whether bounding box a collides with bounding box b
* \param a, b Pointer to bounding box coordinates
*/
static bool boundingBoxInBoundingBox(const double* a,
const double* b)
{
......@@ -686,7 +724,7 @@ public:
return b[0] - eps0 <= a[1] && a[0] <= b[1] + eps0;
}
// Compute the bounding box of a vector of bounding boxes
//! Compute the bounding box of a vector of bounding boxes
static void computeBBoxOfBBoxes(double* bBox,
std::size_t& axis,
const std::vector<double>& leafBoxes,
......@@ -711,7 +749,7 @@ public:
axis = 0;
}
// Sort the bounding boxes along the longest axis
//! Sort the bounding boxes along the longest axis
static void sortBoundingBoxes(std::size_t axis,
const std::vector<double>& leafBoxes,
const std::vector<unsigned int>::iterator& begin,
......@@ -719,8 +757,10 @@ public:
const std::vector<unsigned int>::iterator& end)
{ std::nth_element(begin, middle, end, lessXBox(leafBoxes)); }
// Comparison operators for sorting bounding boxes. There are sorted by their
// mid points along the longest axis
/*!
* \brief Comparison function for sorting bounding boxes on the x-axis
* \note This could be replaced by lambdas
*/
struct lessXBox
{
const std::vector<double>& bBoxes;
......@@ -734,7 +774,14 @@ public:
};
};
//! An intersection object resulting from the collision of two bounding box tree primitives
/*!
* \brief An intersection object resulting from the collision of two bounding box tree primitives
*
* After is has been found that two leaf bounding boxes intersect a primitive test has to be
* performed to see if the actual entities inside the bounding box intersect too. The result
* if such an intersection is found as an object of this class containing the indices of the
* intersecting entities and the corners of the intersection object.
*/
template<class GridView1, class GridView2>
class BoundingBoxTreeIntersection
{
......@@ -746,15 +793,22 @@ public:
BoundingBoxTreeIntersection(unsigned int a, unsigned int b, std::vector<GlobalPosition>&& c)
: a_(a), b_(b), corners_(c) {}
//! Get the index of the intersecting entity belonging to this grid
inline unsigned int first() const
{ return a_; }
//! Get the index of the intersecting entity belonging to the other grid
inline unsigned int second() const
{ return b_; }
//! Get the corners of the intersection geometry
inline std::vector<GlobalPosition> corners() const
{ return corners_; }
/*!
* \brief Check if the corners of this intersection match with the given corners
* \note This is useful to check if the intersection geometry of two intersections coincide.
*/
bool cornersMatch(const std::vector<GlobalPosition>& corners) const
{
if (corners.size() != corners_.size())
......@@ -769,11 +823,13 @@ public:
}
private:
unsigned int a_, b_;
std::vector<GlobalPosition> corners_;
unsigned int a_, b_; //!< Indices of the intersection elements
std::vector<GlobalPosition> corners_; //!< the corner points of the intersection geometry
};
//! An index to element map
/*!
* \brief A class mapping from an element index to elements using element seeds
*/
template <class GridView>
class IndexToElementMap
: public std::vector<typename GridView::Traits::Grid::template Codim<0>::EntitySeed>
......@@ -784,6 +840,7 @@ public:
IndexToElementMap(const GridView& gridView)
: grid_(gridView.grid()) {}
//! get an element from an index t
template<class T>
Element entity(T&& t)
{ return grid_.entity((*this)[std::forward<T>(t)]); }
......@@ -792,12 +849,19 @@ private:
const Grid& grid_;
};
//! The bounding box class. Implements an axis-aligned bounding box tree for grids.
/*!
* \brief An axis-aligned bounding box volume tree implementation
*
* The class constructs a hierarchical structure of bounding box volumes around
* grid entities. This class can be used to efficiently compute intersections
* between a grid and other geometrical object. It only implements the intersection
* of two of such bounding box trees, so that two independent grids can be intersected.
*/
template <class GridView>
class BoundingBoxTree
{
// be friends with all other kinds bounding box trees so that
// they can call each others private methods
//! be friends with all other kinds bounding box trees so that
//! they can call each others private methods
template <class OtherGridView> friend class BoundingBoxTree;
static const int dim = GridView::dimension;
......@@ -814,7 +878,7 @@ public:
BoundingBoxTree(const GridView& leafGridView)
{ build(leafGridView); }
//! Build up bounding box tree for a grid
//! Build up bounding box tree for a grid with leafGridView
void build(const GridView& leafGridView)
{
// clear data if any
......@@ -863,7 +927,7 @@ public:
return entities;
}
//! Compute all intersections between entities and a point
//! Compute all intersections between entities and another bounding box tree
template<class OtherGridView>
std::vector<BoundingBoxTreeIntersection<GridView, OtherGridView>>
computeEntityCollisions(const Dumux::BoundingBoxTree<OtherGridView>& otherTree) const
......@@ -888,25 +952,27 @@ public:
{ return indexToElementMap_->entity(eIdx); }
private:
// Bounding box data. Leaf nodes are indicated by setting child_0 to
// the node itself and child_1 is the index of the entity in the bounding box.
/*!
* \brief Bounding box data structure
* Leaf nodes are indicated by setting child_0 to
* the node itself and child_1 is the index of the entity in the bounding box.
*/
struct BoundingBox
{
unsigned int child_0;
unsigned int child_1;
};
// Vector of bounding boxes
//! Vector of bounding boxes
std::vector<BoundingBox> boundingBoxes_;
// Vector of bounding box coordinates
//! Vector of bounding box coordinates
std::vector<double> boundingBoxCoordinates_;
// Shared pointer to the index to element map
//! Shared pointer to the index to element map
std::shared_ptr<IndexToElementMap<GridView> > indexToElementMap_;
// Clear all data
//! Clear all data
void clear_()
{
boundingBoxes_.clear();
......@@ -914,7 +980,7 @@ private:
if(indexToElementMap_) indexToElementMap_->clear();
}
// Build bounding box tree for all entities recursively
//! Build bounding box tree for all entities recursively
unsigned int build_(const std::vector<double>& leafBoxes,
const std::vector<unsigned int>::iterator& begin,
const std::vector<unsigned int>::iterator& end)
......@@ -954,7 +1020,7 @@ private:
return addBoundingBox_(bBox, b);
}
// Compute collisions with point recursively
//! Compute collisions with point recursively
void computeCollisions_(const Dune::FieldVector<double, dimworld>& point,
unsigned int node,
std::vector<unsigned int>& entities) const
......@@ -988,7 +1054,7 @@ private:
}
}
// Compute collisions with other bounding box tree recursively
//! Compute collisions with other bounding box tree recursively
template <class OtherGridView>
void computeCollisions_(const Dumux::BoundingBoxTree<OtherGridView>& treeB,
unsigned int nodeA,
......@@ -1055,7 +1121,7 @@ private:
}
}
// Add a new bounding box to the tree
//! Add a new bounding box to the tree
inline unsigned int addBoundingBox_(const BoundingBox& bBox,
const double* b)
{
......@@ -1070,24 +1136,24 @@ private:
return boundingBoxes_.size() - 1;
}
// Get an existing bounding box for a given node
//! Get an existing bounding box for a given node
inline const BoundingBox& getBoundingBox_(unsigned int node) const
{ return boundingBoxes_[node]; }
// Get an existing bounding box for a given node
//! Get an existing bounding box for a given node
const double* getBoundingBoxCoordinates_(unsigned int node) const
{ return boundingBoxCoordinates_.data() + 2*dimworld*node; }
// Get the number of bounding boxes currently in the tree
//! Get the number of bounding boxes currently in the tree
inline std::size_t numBoundingBoxes_() const
{ return boundingBoxes_.size(); }
// Check whether a bounding box is a leaf node
// Leaf nodes have itself as child_0
//! Check whether a bounding box is a leaf node
//! Leaf nodes have itself as child_0
inline bool isLeaf_(const BoundingBox& bBox, unsigned int node) const
{ return bBox.child_0 == node; }
// Compute the bounding box of a grid entity
//! Compute the bounding box of a grid entity
template <class Entity>
void computeEntityBoundingBox_(double* b, const Entity& entity) const
{
......
......@@ -31,7 +31,11 @@
namespace Dumux
{
//! A class for geometry collision detection and intersection calculation
/*!
* \brief A class for geometry collision detection and intersection calculation
* The class can be specialized for combinations of dimworld, dim1, dim2, where
* dimworld is the world dimension embedding a grid of dim1 and a grid of dim2.
*/
template
<class Geometry1, class Geometry2,
int dimworld = Geometry1::coorddimension,
......@@ -72,7 +76,8 @@ public:
* \note Algorithm from "Real-Time Collision Detection" by Christer Ericson
* Basis is the theorem that for any two non-intersecting convex polyhedrons
* a separating plane exists.
* \param intersection If the geometries collide intersection holds the corner points of
* \param geo1/geo2 The geometries to intersect
* \param intersection If the geometries collide intersection holds the corner points of
* the intersection object in global coordinates.
*/
static bool collide(const Geometry1& geo1, const Geometry2& geo2, std::vector<GlobalPosition>& intersection)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment