11 #ifndef CUBBYFLOW_QUADTREE_IMPL_HPP 12 #define CUBBYFLOW_QUADTREE_IMPL_HPP 20 bool Quadtree<T>::Node::IsLeaf()
const 22 return firstChild == std::numeric_limits<size_t>::max();
31 m_maxDepth = maxDepth;
37 const double maxEdgeLen = std::max(m_bbox.Width(), m_bbox.Height());
39 m_bbox.lowerCorner +
Vector2D{ maxEdgeLen, maxEdgeLen };
43 m_nodes[0].items.resize(m_items.size());
44 std::iota(m_nodes[0].items.begin(), m_nodes[0].items.end(),
ZERO_SIZE);
46 Build(0, 1, m_bbox, testFunc);
64 best.
distance = std::numeric_limits<double>::max();
68 std::stack<std::pair<const Node*, BoundingBox2D>> todo;
71 const Node* node = m_nodes.data();
73 while (node !=
nullptr)
77 for (
size_t itemIdx : node->items)
79 double d = distanceFunc(m_items[itemIdx], pt);
83 best.
item = &m_items[itemIdx];
93 node = todo.top().first;
94 bound = todo.top().second;
101 typedef std::tuple<const Node*, double, BoundingBox2D> NodeDistBox;
102 std::array<NodeDistBox, 4> childDistSqrPairs;
103 const auto MidPoint = bound.
MidPoint();
104 for (
int i = 0; i < 4; ++i)
106 const Node* child = &m_nodes[node->firstChild + i];
107 const auto childBound =
112 childDistSqrPairs[i] =
113 std::make_tuple(child, distMinSqr, childBound);
115 std::sort(childDistSqrPairs.begin(), childDistSqrPairs.end(),
116 [](
const NodeDistBox& a,
const NodeDistBox& b) {
117 return std::get<1>(a) > std::get<1>(b);
120 for (
int i = 0; i < 4; ++i)
122 const auto& childPair = childDistSqrPairs[i];
123 if (std::get<1>(childPair) < bestDistSqr)
125 todo.emplace(std::get<0>(childPair),
126 std::get<2>(childPair));
135 node = todo.top().first;
136 bound = todo.top().second;
144 template <
typename T>
148 return Intersects(box, testFunc, 0, m_bbox);
151 template <
typename T>
155 return Intersects(ray, testFunc, 0, m_bbox);
158 template <
typename T>
163 ForEachIntersectingItem(box, testFunc, visitorFunc, 0, m_bbox);
166 template <
typename T>
171 ForEachIntersectingItem(ray, testFunc, visitorFunc, 0, m_bbox);
174 template <
typename T>
179 best.
distance = std::numeric_limits<double>::max();
182 return ClosestIntersection(ray, testFunc, 0, m_bbox, best);
185 template <
typename T>
188 return m_items.begin();
191 template <
typename T>
194 return m_items.end();
197 template <
typename T>
200 return m_items.begin();
203 template <
typename T>
206 return m_items.end();
209 template <
typename T>
212 return m_items.size();
215 template <
typename T>
221 template <
typename T>
224 return m_nodes.size();
227 template <
typename T>
230 return m_nodes[nodeIdx].items;
233 template <
typename T>
236 return m_nodes[nodeIdx].firstChild + childIdx;
239 template <
typename T>
245 template <
typename T>
251 template <
typename T>
256 if (depth < m_maxDepth && !m_nodes[nodeIdx].items.empty())
258 const size_t firstChild = m_nodes[nodeIdx].firstChild = m_nodes.size();
259 m_nodes.resize(m_nodes[nodeIdx].firstChild + 4);
263 for (
int i = 0; i < 4; ++i)
268 auto& currentItems = m_nodes[nodeIdx].items;
269 for (
size_t i = 0; i < currentItems.size(); ++i)
271 size_t currentItem = currentItems[i];
272 for (
int j = 0; j < 4; ++j)
274 if (testFunc(m_items[currentItem], bboxPerNode[j]))
276 m_nodes[firstChild + j].items.push_back(currentItem);
282 currentItems.clear();
285 for (
int i = 0; i < 4; ++i)
287 Build(firstChild + i, depth + 1, bboxPerNode[i], testFunc);
292 template <
typename T>
302 const Node& node = m_nodes[nodeIdx];
304 if (node.items.size() > 0)
306 for (
size_t itemIdx : node.items)
308 if (testFunc(m_items[itemIdx], box))
315 if (node.firstChild != std::numeric_limits<size_t>::max())
317 for (
int i = 0; i < 4; ++i)
319 if (Intersects(box, testFunc, node.firstChild + i,
330 template <
typename T>
340 const Node& node = m_nodes[nodeIdx];
342 if (node.items.size() > 0)
344 for (
size_t itemIdx : node.items)
346 if (testFunc(m_items[itemIdx], ray))
353 if (node.firstChild != std::numeric_limits<size_t>::max())
355 for (
int i = 0; i < 4; ++i)
357 if (Intersects(ray, testFunc, node.firstChild + i,
368 template <
typename T>
379 const Node& node = m_nodes[nodeIdx];
381 if (node.items.size() > 0)
383 for (
size_t itemIdx : node.items)
385 if (testFunc(m_items[itemIdx], box))
387 visitorFunc(m_items[itemIdx]);
392 if (node.firstChild != std::numeric_limits<size_t>::max())
394 for (
int i = 0; i < 4; ++i)
396 ForEachIntersectingItem(
397 box, testFunc, visitorFunc, node.firstChild + i,
403 template <
typename T>
414 const Node& node = m_nodes[nodeIdx];
416 if (node.items.size() > 0)
418 for (
size_t itemIdx : node.items)
420 if (testFunc(m_items[itemIdx], ray))
422 visitorFunc(m_items[itemIdx]);
427 if (node.firstChild != std::numeric_limits<size_t>::max())
429 for (
int i = 0; i < 4; ++i)
431 ForEachIntersectingItem(
432 ray, testFunc, visitorFunc, node.firstChild + i,
438 template <
typename T>
449 const Node& node = m_nodes[nodeIdx];
451 if (node.items.size() > 0)
453 for (
size_t itemIdx : node.items)
455 double dist = testFunc(m_items[itemIdx], ray);
459 best.
item = &m_items[itemIdx];
464 if (node.firstChild != std::numeric_limits<size_t>::max())
466 for (
int i = 0; i < 4; ++i)
468 best = ClosestIntersection(
469 ray, testFunc, node.firstChild + i,
ValueType DistanceSquaredTo(const MatrixExpression< T, R, C, E > &other) const
Returns the squared distance to the other vector.
VectorType upperCorner
Upper corner of the bounding box.
Definition: BoundingBox.hpp:148
N-D nearest neighbor query result.
Definition: NearestNeighborQueryEngine.hpp:23
VectorType Corner(size_t idx) const
Returns corner position. Index starts from x-first order.
Definition: BoundingBox-Impl.hpp:240
Class for N-D ray.
Definition: Ray.hpp:25
N-D axis-aligned bounding box class.
Definition: BoundingBox.hpp:46
size_t GetNumberOfNodes() const
Returns the number of quadtree nodes.
Definition: Quadtree-Impl.hpp:222
size_t GetMaxDepth() const
Returns the maximum depth of the tree.
Definition: Quadtree-Impl.hpp:246
BoundingBox2< double > BoundingBox2D
Definition: BoundingBox.hpp:159
size_t GetChildIndex(size_t nodeIdx, size_t childIdx) const
Returns a child's index for given node.
Definition: Quadtree-Impl.hpp:234
NearestNeighborQueryResult2< T > Nearest(const Vector2D &pt, const NearestNeighborDistanceFunc2< T > &distanceFunc) const override
Definition: Quadtree-Impl.hpp:59
void ForEachIntersectingItem(const BoundingBox2D &box, const BoxIntersectionTestFunc2< T > &testFunc, const IntersectionVisitorFunc< T > &visitorFunc) const override
Invokes visitorFunc for every intersecting items.
Definition: Quadtree-Impl.hpp:159
void Build(const std::vector< T > &items, const BoundingBox2D &bound, const BoxIntersectionTestFunc2< T > &testFunc, size_t maxDepth)
Definition: Quadtree-Impl.hpp:26
bool Intersects(const RayType &ray) const
Returns true if the input ray is intersecting with this box.
Definition: BoundingBox-Impl.hpp:119
bool Intersects(const BoundingBox2D &box, const BoxIntersectionTestFunc2< T > &testFunc) const override
Returns true if given box intersects with any of the stored items.
Definition: Quadtree-Impl.hpp:145
const std::vector< size_t > & GetItemsAtNode(size_t nodeIdx) const
Returns the list of the items for given node index.
Definition: Quadtree-Impl.hpp:228
Definition: Matrix.hpp:27
void Clear()
Clears all the contents of this instance.
Definition: Quadtree-Impl.hpp:50
N-D closest intersection query result.
Definition: IntersectionQueryEngine.hpp:25
Definition: pybind11Utils.hpp:20
GetRayIntersectionFunc< T, 2 > GetRayIntersectionFunc2
2-D ray-item closest intersection evaluation function.
Definition: IntersectionQueryEngine.hpp:85
const T * item
Definition: NearestNeighborQueryEngine.hpp:25
double distance
Definition: IntersectionQueryEngine.hpp:28
Iterator begin()
Returns the begin iterator of the item.
Definition: Quadtree-Impl.hpp:186
size_t GetNumberOfItems() const
Returns the number of items.
Definition: Quadtree-Impl.hpp:210
BoxIntersectionTestFunc< T, 2 > BoxIntersectionTestFunc2
2-D box-item intersection test function.
Definition: IntersectionQueryEngine.hpp:59
Iterator end()
Returns the end iterator of the item.
Definition: Quadtree-Impl.hpp:192
constexpr size_t ZERO_SIZE
Zero size_t.
Definition: Constants.hpp:20
const BoundingBox2D & GetBoundingBox() const
Returns the bounding box of this quadtree.
Definition: Quadtree-Impl.hpp:240
RayIntersectionTestFunc< T, 2 > RayIntersectionTestFunc2
2-D ray-item intersection test function.
Definition: IntersectionQueryEngine.hpp:72
bool Overlaps(const BoundingBox &other) const
Returns true of this box and other box overlaps.
Definition: BoundingBox-Impl.hpp:90
const T * item
Definition: IntersectionQueryEngine.hpp:27
ClosestIntersectionQueryResult2< T > ClosestIntersection(const Ray2D &ray, const GetRayIntersectionFunc2< T > &testFunc) const override
Returns the closest intersection for given ray.
Definition: Quadtree-Impl.hpp:175
VectorType MidPoint() const
Returns the mid-point of this box.
Definition: BoundingBox-Impl.hpp:194
const T & GetItem(size_t i) const
Returns the item at i.
Definition: Quadtree-Impl.hpp:216
typename ContainerType::const_iterator ConstIterator
Definition: Quadtree.hpp:35
double distance
Definition: NearestNeighborQueryEngine.hpp:26
std::function< void(const T &)> IntersectionVisitorFunc
Visitor function which is invoked for each intersecting item.
Definition: IntersectionQueryEngine.hpp:93
typename ContainerType::iterator Iterator
Definition: Quadtree.hpp:34
NearestNeighborDistanceFunc< T, 2 > NearestNeighborDistanceFunc2
2-D nearest neighbor distance measure function.
Definition: NearestNeighborQueryEngine.hpp:44