From 868724e14e3839b92046ee44e8605a75b6be8c94 Mon Sep 17 00:00:00 2001 From: Timo Koch <timo.koch@iws.uni-stuttgart.de> Date: Fri, 29 Apr 2016 18:00:39 +0200 Subject: [PATCH] [doc] Improve AABB tree / geometry collision docstrings --- dumux/common/boundingboxtree.hh | 180 ++++++++++++++++++++---------- dumux/common/geometrycollision.hh | 9 +- 2 files changed, 130 insertions(+), 59 deletions(-) diff --git a/dumux/common/boundingboxtree.hh b/dumux/common/boundingboxtree.hh index 12490960ce..50de581baf 100644 --- a/dumux/common/boundingboxtree.hh +++ b/dumux/common/boundingboxtree.hh @@ -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 { diff --git a/dumux/common/geometrycollision.hh b/dumux/common/geometrycollision.hh index b7afe67ed7..a7d5e1823e 100644 --- a/dumux/common/geometrycollision.hh +++ b/dumux/common/geometrycollision.hh @@ -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) -- GitLab