More fixes from review

This commit is contained in:
Simon Giraudot 2021-02-02 08:17:54 +01:00
parent 1db1829b91
commit 8d30b39b73
5 changed files with 56 additions and 23 deletions

View File

@ -61,9 +61,15 @@ behave as a %quadtree. For convenience, the alias `Quadtree` is provided.
The following example shows how to create a %quadtree object from a The following example shows how to create a %quadtree object from a
vector of `Point_2` objects and refine it, which means constructing vector of `Point_2` objects and refine it, which means constructing
the tree's space subdivision itself, using a maximum depth of 10 and a the tree's space subdivision itself, using a maximum depth of 10 and a
maximum number of inliers per node (bucket size) of 5: maximum number of inliers per node (bucket size) of 5. The refinement
is stopped as soon as one of the condition is violated: if a node has
more inliers than `bucket_size` but is already at `max_depth`, it is
not split. Similarly, a node that is at a depth smaller than
`max_depth` but already has fewer inliers than `bucket_size` is not
split.
\cgalExample{Orthtree/quadtree_build_from_point_vector.cpp}
\CGALEXAMPLE{Orthtree/quadtree_build_from_point_vector.cpp}
\subsection Section_Orthtree_Point_Vector Building an Octree \subsection Section_Orthtree_Point_Vector Building an Octree

View File

@ -168,7 +168,15 @@ public:
The constructed orthtree has a root node, with no children, that The constructed orthtree has a root node, with no children, that
contains the points passed. That root node has a bounding box that contains the points passed. That root node has a bounding box that
encloses all of the points passed, with padding according to the encloses all of the points passed, with padding according to the
`enlarge_ratio`. This single-node orthtree is valid and compatible `enlarge_ratio`.
That root node is built as a `n`-cube (square in 2D, cube in 3D,
etc.) whose edge size is the longest bounding box edge multiplied
by `enlarge_ratio`. Using an `enlarge_ratio>1.0` prevents some
points from being exactly on the border of some cells, which can
lead to over-refinement.
This single-node orthtree is valid and compatible
with all Orthtree functionality, but any performance benefits are with all Orthtree functionality, but any performance benefits are
unlikely to be realized until `refine()` is called. unlikely to be realized until `refine()` is called.
@ -278,8 +286,12 @@ public:
The split predicate is a `std::function` that takes a Node and The split predicate is a `std::function` that takes a Node and
returns a Boolean value (where `true` implies that a Node needs to returns a Boolean value (where `true` implies that a Node needs to
be split, `false` that the Node should be a leaf). This function be split, `false` that the Node should be a leaf).
function may be called several times with different predicate.
This function function may be called several times with different
predicates: in that case, nodes already split are left unaltered,
while nodes that were not split and for which `split_predicate`
returns `true` are split.
\param split_predicate determines whether or not a node needs to \param split_predicate determines whether or not a node needs to
be subdivided. be subdivided.
@ -333,7 +345,13 @@ public:
This is equivalent to calling This is equivalent to calling
`refine(Orthtrees::Maximum_depth_and_maximum_number_of_inliers(min_depth, `refine(Orthtrees::Maximum_depth_and_maximum_number_of_inliers(min_depth,
bucket_size))` bucket_size))`.
The refinement is stopped as soon as one of the condition is
violated: if a node has more inliers than `bucket_size` but is
already at `max_depth`, it is not split. Similarly, a node that is
at a depth smaller than `max_depth` but already has fewer inliers
than `bucket_size`, it is not split.
\param max_depth deepest a tree is allowed to be (nodes at this depth will not be split). \param max_depth deepest a tree is allowed to be (nodes at this depth will not be split).
\param bucket_size maximum points a node is allowed to contain. \param bucket_size maximum points a node is allowed to contain.
@ -420,7 +438,7 @@ public:
\sa `Node::operator[]()` \sa `Node::operator[]()`
\param index the index of the child node. \param index the index of the child node.
\return a reference to the node. \return the accessed node.
*/ */
Node operator[](std::size_t index) const { return m_root[index]; } Node operator[](std::size_t index) const { return m_root[index]; }

View File

@ -161,15 +161,17 @@ private:
/*! /*!
\brief creates a new node, optionally as the child of a parent \brief creates a new node, optionally as the child of a parent
If no parent is provided, the node created is assumed to be the root of a tree. If no parent is provided, the node created is assumed to be the
This means that the parent reference is a nullptr, and the depth is zero. root of a tree. This means that `parent.is_null()` returns
If a parent is provided, the node becomes the child of that parent. `true`, and the depth is zero. If a parent is provided, the node
In that case, an index should be passed, telling this node its relationship to its parent. becomes the child of that parent. In that case, an index should
Depth and global coordinates are automatically determined in the constructor, be passed, telling this node its relationship to its parent.
and should generally be considered immutable after construction. Depth and global coordinates are automatically determined in the
constructor, and should generally be considered immutable after
construction.
\param parent A reference to the node containing this one \param parent the node containing this one
\param index This node's relationship to its parent \param index this node's relationship to its parent
*/ */
explicit Node(Self parent, Local_coordinates local_coordinates) explicit Node(Self parent, Local_coordinates local_coordinates)
: m_data (new Data(parent)) { : m_data (new Data(parent)) {

View File

@ -38,7 +38,7 @@ public:
m_bucket_size(bucket_size) {} m_bucket_size(bucket_size) {}
/*! /*!
\brief returns `true` if `n` should be splitted, `false` otherwise. \brief returns `true` if `n` should be split, `false` otherwise.
*/ */
template<typename Node> template<typename Node>
bool operator()(const Node &n) const { bool operator()(const Node &n) const {
@ -50,7 +50,7 @@ public:
\ingroup PkgOrthtreeSplitPredicates \ingroup PkgOrthtreeSplitPredicates
\brief A class used to choose when a node should be split depending on the depth. \brief A class used to choose when a node should be split depending on the depth.
This predicate makes a node splitted if its depth is lower than a certain limit. This predicate makes a node split if its depth is lower than a certain limit.
*/ */
class Maximum_depth { class Maximum_depth {
@ -64,7 +64,7 @@ public:
Maximum_depth(std::size_t max_depth) : m_max_depth(max_depth) {} Maximum_depth(std::size_t max_depth) : m_max_depth(max_depth) {}
/*! /*!
\brief returns `true` if `n` should be splitted, `false` otherwise. \brief returns `true` if `n` should be split, `false` otherwise.
*/ */
template<typename Node> template<typename Node>
bool operator()(const Node &n) const { bool operator()(const Node &n) const {
@ -76,9 +76,16 @@ public:
\ingroup PkgOrthtreeSplitPredicates \ingroup PkgOrthtreeSplitPredicates
\brief A class used to choose when a node should be split depending on the depth and the number of inliers. \brief A class used to choose when a node should be split depending on the depth and the number of inliers.
This predicate makes a note splitted if it contains more than a This predicate makes a note split if it contains more than a
certain number of items and if its depth is lower than a certain certain number of items and if its depth is lower than a certain
limit. limit.
The refinement is stopped as soon as one of the condition is
violated: if a node has more inliers than `bucket_size` but is
already at `max_depth`, it is not split. Similarly, a node that is
at a depth smaller than `max_depth` but already has fewer inliers
than `bucket_size`, it is not split.
*/ */
class Maximum_depth_and_maximum_number_of_inliers { class Maximum_depth_and_maximum_number_of_inliers {
@ -93,7 +100,7 @@ public:
m_max_depth(max_depth), m_bucket_size(bucket_size) {} m_max_depth(max_depth), m_bucket_size(bucket_size) {}
/*! /*!
\brief returns `true` if `n` should be splitted, `false` otherwise. \brief returns `true` if `n` should be split, `false` otherwise.
*/ */
template<template Node> template<template Node>
bool operator()(const Node &n) const { bool operator()(const Node &n) const {

View File

@ -89,7 +89,7 @@ Node deepest_first_child(Node n) {
/*! /*!
\ingroup PkgOrthtreeTraversal \ingroup PkgOrthtreeTraversal
\brief A class used to traverse an orthtree in a preorder way. \brief A class used for performing a preorder traversal.
A preorder traversal starts from the root towards the leaves. A preorder traversal starts from the root towards the leaves.
@ -122,7 +122,7 @@ struct Preorder_traversal {
/*! /*!
\ingroup PkgOrthtreeTraversal \ingroup PkgOrthtreeTraversal
\brief A class used to traverse an orthtree in a postorder way. \brief A class used for performing a postorder traversal.
A postorder traversal starts from the leaves towards the root. A postorder traversal starts from the leaves towards the root.
@ -150,7 +150,7 @@ struct Postorder_traversal {
/*! /*!
\ingroup PkgOrthtreeTraversal \ingroup PkgOrthtreeTraversal
\brief A class used to traverse the leaves of an orthtree. \brief A class used for performing a traversal on leaves only.
All non-leave nodes are ignored. All non-leave nodes are ignored.