9 #ifndef CUBBYFLOW_QUADTREE_IMPL_H 10 #define CUBBYFLOW_QUADTREE_IMPL_H 18 bool Quadtree<T>::Node::IsLeaf()
const 20 return firstChild == std::numeric_limits<size_t>::max();
34 m_maxDepth = maxDepth;
40 double maxEdgeLen = std::max(m_bbox.GetWidth(), m_bbox.GetHeight());
45 m_nodes[0].items.resize(m_items.size());
46 std::iota(m_nodes[0].items.begin(), m_nodes[0].items.end(),
ZERO_SIZE);
48 Build(0, 1, m_bbox, testFunc);
66 best.
distance = std::numeric_limits<double>::max();
70 std::stack<std::pair<const Node*, BoundingBox2D>> todo;
73 const Node* node = m_nodes.data();
75 while (node !=
nullptr)
79 for (
size_t itemIdx : node->items)
81 double d = distanceFunc(m_items[itemIdx], pt);
85 best.
item = &m_items[itemIdx];
95 node = todo.top().first;
96 bound = todo.top().second;
103 typedef std::tuple<const Node*, double, BoundingBox2D> NodeDistBox;
104 std::array<NodeDistBox, 4> childDistSqrPairs;
105 const auto MidPoint = bound.
MidPoint();
106 for (
int i = 0; i < 4; ++i)
108 const Node* child = &m_nodes[node->firstChild + i];
113 childDistSqrPairs[i] = std::make_tuple(child, distMinSqr, childBound);
115 std::sort(childDistSqrPairs.begin(), childDistSqrPairs.end(),
116 [](
const NodeDistBox& a,
const NodeDistBox& b)
118 return std::get<1>(a) > std::get<1>(b);
121 for (
int i = 0; i < 4; ++i)
123 const auto& childPair = childDistSqrPairs[i];
124 if (std::get<1>(childPair) < bestDistSqr)
126 todo.emplace(std::get<0>(childPair), std::get<2>(childPair));
135 node = todo.top().first;
136 bound = todo.top().second;
144 template <
typename T>
149 return IsIntersects(box, testFunc, 0, m_bbox);
152 template <
typename T>
156 return IsIntersects(ray, testFunc, 0, m_bbox);
159 template <
typename T>
164 ForEachIntersectingItem(box, testFunc, visitorFunc, 0, m_bbox);
167 template <
typename T>
172 ForEachIntersectingItem(ray, testFunc, visitorFunc, 0, m_bbox);
175 template <
typename T>
180 best.
distance = std::numeric_limits<double>::max();
183 return GetClosestIntersection(ray, testFunc, 0, m_bbox, best);
186 template <
typename T>
189 return m_items.begin();
192 template <
typename T>
195 return m_items.end();
198 template <
typename T>
201 return m_items.begin();
204 template <
typename T>
207 return m_items.end();
210 template <
typename T>
213 return m_items.size();
216 template <
typename T>
222 template <
typename T>
225 return m_nodes.size();
228 template <
typename T>
231 return m_nodes[nodeIdx].items;
234 template <
typename T>
237 return m_nodes[nodeIdx].firstChild + childIdx;
240 template <
typename T>
246 template <
typename T>
252 template <
typename T>
257 if (depth < m_maxDepth && !m_nodes[nodeIdx].items.empty())
259 size_t firstChild = m_nodes[nodeIdx].firstChild = m_nodes.size();
260 m_nodes.resize(m_nodes[nodeIdx].firstChild + 4);
264 for (
int i = 0; i < 4; ++i)
269 auto& currentItems = m_nodes[nodeIdx].items;
270 for (
size_t i = 0; i < currentItems.size(); ++i)
272 size_t currentItem = currentItems[i];
273 for (
int j = 0; j < 4; ++j)
275 if (testFunc(m_items[currentItem], bboxPerNode[j]))
277 m_nodes[firstChild + j].items.push_back(currentItem);
283 currentItems.clear();
286 for (
int i = 0; i < 4; ++i)
288 Build(firstChild + i, depth + 1, bboxPerNode[i], testFunc);
293 template <
typename T>
295 const BoxIntersectionTestFunc2<T>& testFunc,
298 if (!box.Overlaps(bound))
303 const Node& node = m_nodes[nodeIdx];
305 if (node.items.size() > 0)
307 for (
size_t itemIdx : node.items)
309 if (testFunc(m_items[itemIdx], box))
316 if (node.firstChild != std::numeric_limits<size_t>::max())
318 for (
int i = 0; i < 4; ++i)
320 if (IsIntersects(box, testFunc, node.firstChild + i,
BoundingBox2D(bound.Corner(i), bound.MidPoint())))
330 template <
typename T>
332 const RayIntersectionTestFunc2<T>& testFunc,
335 if (!bound.Intersects(ray))
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 (IsIntersects(ray, testFunc, node.firstChild + i,
BoundingBox2D(bound.Corner(i), bound.MidPoint())))
367 template <
typename T>
369 const BoundingBox2D& box,
const BoxIntersectionTestFunc2<T>& testFunc,
370 const IntersectionVisitorFunc2<T>& visitorFunc,
size_t nodeIdx,
373 if (!box.Overlaps(bound))
378 const Node& node = m_nodes[nodeIdx];
380 if (node.items.size() > 0)
382 for (
size_t itemIdx : node.items)
384 if (testFunc(m_items[itemIdx], box))\
386 visitorFunc(m_items[itemIdx]);
391 if (node.firstChild != std::numeric_limits<size_t>::max())
393 for (
int i = 0; i < 4; ++i)
395 ForEachIntersectingItem(
396 box, testFunc, visitorFunc, node.firstChild + i,
402 template <
typename T>
404 const Ray2D& ray,
const RayIntersectionTestFunc2<T>& testFunc,
405 const IntersectionVisitorFunc2<T>& visitorFunc,
size_t nodeIdx,
408 if (!bound.Intersects(ray))
413 const Node& node = m_nodes[nodeIdx];
415 if (node.items.size() > 0)
417 for (
size_t itemIdx : node.items)
419 if (testFunc(m_items[itemIdx], ray))
421 visitorFunc(m_items[itemIdx]);
426 if (node.firstChild != std::numeric_limits<size_t>::max())
428 for (
int i = 0; i < 4; ++i)
430 ForEachIntersectingItem(
431 ray, testFunc, visitorFunc, node.firstChild + i,
437 template <
typename T>
439 const Ray2D& ray,
const GetRayIntersectionFunc2<T>& testFunc,
441 ClosestIntersectionQueryResult2<T> best)
const 443 if (!bound.Intersects(ray))
448 const Node& node = m_nodes[nodeIdx];
450 if (node.items.size() > 0)
452 for (
size_t itemIdx : node.items)
454 double dist = testFunc(m_items[itemIdx], ray);
455 if (dist < best.distance)
457 best.distance = dist;
458 best.item = &m_items[itemIdx];
463 if (node.firstChild != std::numeric_limits<size_t>::max())
465 for (
int i = 0; i < 4; ++i)
467 best = GetClosestIntersection(
468 ray, testFunc, node.firstChild + i,
NearestNeighborQueryResult2< T > GetNearestNeighbor(const Vector2D &pt, const NearestNeighborDistanceFunc2< T > &distanceFunc) const override
Definition: Quadtree-Impl.h:61
Quadtree()
Default constructor.
Definition: Quadtree-Impl.h:24
double distance
Definition: NearestNeighborQueryEngine2.h:21
Vector2< T > MidPoint() const
Returns the mid-point of this box.
Definition: BoundingBox2-Impl.h:163
Ray2< double > Ray2D
Double-type 2-D ray.
Definition: Ray2.h:54
Closest intersection query result.
Definition: IntersectionQueryEngine2.h:19
Class for 2-D ray.
Definition: Ray2.h:23
size_t GetNumberOfNodes() const
Returns the number of quadtree nodes.
Definition: Quadtree-Impl.h:223
size_t GetMaxDepth() const
Returns the maximum depth of the tree.
Definition: Quadtree-Impl.h:247
const T * item
Definition: IntersectionQueryEngine2.h:21
BoundingBox2< double > BoundingBox2D
Double-type 2-D BoundingBox.
Definition: BoundingBox2.h:126
std::function< bool(const T &, const BoundingBox2D &)> BoxIntersectionTestFunc2
Box-item intersection test function.
Definition: IntersectionQueryEngine2.h:31
size_t GetChildIndex(size_t nodeIdx, size_t childIdx) const
Returns a child's index for given node.
Definition: Quadtree-Impl.h:235
Nearest neighbor query result.
Definition: NearestNeighborQueryEngine2.h:18
Vector2< T > upperCorner
Upper corner of the bounding box.
Definition: BoundingBox2.h:51
T DistanceSquaredTo(const Vector &other) const
Returns the squared distance to the other vector.
Definition: Vector2-Impl.h:308
void Build(const std::vector< T > &items, const BoundingBox2D &bound, const BoxIntersectionTestFunc2< T > &testFunc, size_t maxDepth)
Definition: Quadtree-Impl.h:30
const std::vector< size_t > & GetItemsAtNode(size_t nodeIdx) const
Returns the list of the items for given noide index.
Definition: Quadtree-Impl.h:229
bool IsIntersects(const BoundingBox2D &box, const BoxIntersectionTestFunc2< T > &testFunc) const override
Returns true if given box intersects with any of the stored items.
Definition: Quadtree-Impl.h:145
const T * item
Definition: NearestNeighborQueryEngine2.h:20
void Clear()
Clears all the contents of this instance.
Definition: Quadtree-Impl.h:52
2-D axis-aligned bounding box class.
Definition: BoundingBox2.h:44
Definition: pybind11Utils.h:24
Vector2< double > Vector2D
Double-type 2D vector.
Definition: Vector2.h:341
void ForEachIntersectingItem(const BoundingBox2D &box, const BoxIntersectionTestFunc2< T > &testFunc, const IntersectionVisitorFunc2< T > &visitorFunc) const override
Invokes visitorFunc for every intersecting items.
Definition: Quadtree-Impl.h:160
std::function< void(const T &)> IntersectionVisitorFunc2
Visitor function which is invoked for each intersecting item.
Definition: IntersectionQueryEngine2.h:43
double distance
Definition: IntersectionQueryEngine2.h:22
Iterator begin()
Returns the begin iterator of the item.
Definition: Quadtree-Impl.h:187
size_t GetNumberOfItems() const
Returns the number of items.
Definition: Quadtree-Impl.h:211
ClosestIntersectionQueryResult2< T > GetClosestIntersection(const Ray2D &ray, const GetRayIntersectionFunc2< T > &testFunc) const override
Returns the closest intersection for given ray.
Definition: Quadtree-Impl.h:176
Iterator end()
Returns the end iterator of the item.
Definition: Quadtree-Impl.h:193
constexpr size_t ZERO_SIZE
Zero size_t.
Definition: Constants.h:18
const BoundingBox2D & GetBoundingBox() const
Returns the bounding box of this quadtree.
Definition: Quadtree-Impl.h:241
Vector2< T > Corner(size_t idx) const
Returns corner position. Index starts from x-first order.
Definition: BoundingBox2-Impl.h:215
2-D vector class.
Definition: Vector2.h:26
const T & GetItem(size_t i) const
Returns the item at i.
Definition: Quadtree-Impl.h:217
std::function< double(const T &, const Ray2D &)> GetRayIntersectionFunc2
Ray-item closest intersection evaluation function.
Definition: IntersectionQueryEngine2.h:39
typename ContainerType::const_iterator ConstIterator
Definition: Quadtree.h:32
std::function< bool(const T &, const Ray2D &)> RayIntersectionTestFunc2
Ray-item intersection test function.
Definition: IntersectionQueryEngine2.h:35
std::function< double(const T &, const Vector2D &)> NearestNeighborDistanceFunc2
Nearest neighbor distance measure function.
Definition: NearestNeighborQueryEngine2.h:26
typename ContainerType::iterator Iterator
Definition: Quadtree.h:31