Visual Computing Library  devel
Loading...
Searching...
No Matches
abstract_grid.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_SPACE_COMPLEX_GRID_ABSTRACT_GRID_H
24#define VCL_SPACE_COMPLEX_GRID_ABSTRACT_GRID_H
25
26#include <vclib/algorithms/core.h>
27#include <vclib/mesh.h>
28#include <vclib/space/core.h>
29
30#include <set>
31
32namespace vcl {
33
34/*
35 * Developer Documentation
36 * A class that derives from an AbstractGrid must store, in some way, an
37 * association between a GridCell position (a Point of unsigned integers) and
38 * elements of type ValueType. Each cell may contain more than one element
39 * value, and each element value may be stored in more than one cell if it
40 * intersects with more than one cell.
41 *
42 * This class is made using CRTP static polymorphism
43 * (https: *en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
44 * The last template parameter, is the Derived class that derives from this
45 * grid. This allows to avoid calling virtual member functions, which would be
46 * called very often and may cause a significant overhead during queries.
47 *
48 * What you need to do is to declared your Grid Data Structure as follows:
49 *
50 * template<typename GridType, typename ValueType>
51 * class MyDSGrid :
52 * public AbstractGrid<GridType, ValueType, MyDSGrid<GridType, ValueType>>
53 * { ... };
54 *
55 * Make sure that your class:
56 * - declares the AbstractGrid class as friend (if one of the following member
57 * functions is
58 * protected/private);
59 * - implements iterators Iterator and ConstIterator that iterate over pairs of
60 * <KeyType, ValueType> (see below for more details)
61 * - implements the following member functions:
62 * - std::pair<Iterator, Iterator> valuesInCell(const KeyType) -> returns a
63 * pair of begin-end iterators that will allow to cycle over the elements
64 * contained in a cell. this function must be overloaded both in const and
65 * non-const versions, returning proper const or non-const iterators.
66 * - bool insertInCell(const KeyType&, const ValueType&) -> inserts the
67 * element in a Grid Cell. The returned type tells if the element has been
68 * inserted (in some implementations, insertion could not happen, e.g. when
69 * duplicates are not allowed).
70 * - bool eraseInCell(const KeyType&, const ValueType&) -> erases all the
71 * element equal to the given element from the given Grid Cell. The returned
72 * type tells if the element has been erased from the given cell.
73 * - Iterator end() -> classic member function that returns the end iterator
74 *
75 * Iterators of your class must:
76 * - Iterate over pairs of <KeyType, ValueType&>:
77 * - operator*() returns a pair having first member that is the key, and
78 * second member that is a reference to the value
79 * - operator->() return a pointer to the same pair
80 * - operator+() and operator+(int), that moves the iterator in the same cell if
81 * there are more values in it, or moves in the next cell-element
82 *
83 * You can reimplement in your derived class all the member functions
84 * implemented in this class that may take advantage of a speedup depending on
85 * the internal storage. You can also hide all the member functions implemented
86 * in this class that do not apply to your derived class.
87 */
88
104template<typename GridType, typename ValueType, typename DerivedGrid>
105class AbstractGrid : public GridType
106{
107public:
115 using IntersectsCellFunction = std::function<bool(
116 const typename GridType::BBoxType&,
118
119protected:
120 /* custom function that checks if a value intersects with a cell (a box)
121 if not initialized, bounding box of value will be used to check if it is
122 in cell */
123 IntersectsCellFunction mIntersectsFun;
124
125public:
126 using KeyType = GridType::CellPos;
127
135 template<typename QueryValueType>
136 using QueryDistFunction = std::function<typename GridType::ScalarType(
137 const QueryValueType&,
139
151 template<typename QueryValueType>
153 std::function<typename GridType::ScalarType(
154 const QueryValueType&,
156 typename GridType::ScalarType)>;
157
158 bool cellEmpty(const KeyType& k) const
159 {
160 auto p = derived()->valuesInCell(k);
161 return p.first == p.second;
162 }
163
164 std::size_t countInCell(const KeyType& k) const
165 {
166 auto p = derived()->valuesInCell(k);
167 return std::distance(p.first, p.second);
168 }
169
181 bool insert(const ValueType& v)
182 {
183 const VT* vv = addressOfObj(v);
184
185 // if vv is a valid pointer (ValueType, or ValueType* if ValueType is
186 // not a pointer)
187 if (vv) {
188 // first and last cell where insert (could be the same)
189 KeyType bmin, bmax;
190
191 // if ValueType is Point, Point*, Vertex, Vertex*
192 if constexpr (PointConcept<VT> || VertexConcept<VT>) {
193 typename GridType::PointType p;
194 if constexpr (PointConcept<VT>)
195 p = *vv;
196 else
197 p = vv->position();
198 bmin = bmax = GridType::cell(p);
199 }
200 else { // else, call the boundingBox function
201 // bounding box of value
202 typename GridType::BBoxType bb = boundingBox(*vv);
203
204 bmin = GridType::cell(bb.min()); // first cell where insert
205 bmax = GridType::cell(bb.max()); // last cell where insert
206 }
207
208 bool ins = false;
209
210 // custom intersection function between cell and value
211 if (mIntersectsFun) {
212 for (const auto& cell : GridType::cells(bmin, bmax)) {
213 if (mIntersectsFun(
214 GridType::cellBox(cell), dereferencePtr(v))) {
215 ins |= derived()->insertInCell(cell, v);
216 }
217 }
218 }
219 else {
220 for (const auto& cell : GridType::cells(bmin, bmax)) {
221 ins |= derived()->insertInCell(cell, v);
222 }
223 }
224 return ins;
225 }
226 return false;
227 }
228
236 template<typename ObjIterator>
238 {
239 uint cnt = 0;
240 for (ObjIterator it = begin; it != end; ++it)
241 if (insert(*it))
242 cnt++;
243 return cnt;
244 }
245
253 template<Range Rng>
255 {
256 return insert(std::ranges::begin(r), std::ranges::end(r));
257 }
258
259 bool erase(const ValueType& v)
260 {
261 const VT* vv = addressOfObj(v);
262
263 if (vv) {
264 // first and last cell where erase (could be the same)
265 KeyType bmin, bmax;
266
267 if constexpr (PointConcept<VT> || VertexConcept<VT>) {
268 typename GridType::PointType p;
269 if constexpr (PointConcept<VT>)
270 p = *vv;
271 else
272 p = vv->position();
273 bmin = bmax = GridType::cell(p);
274 }
275 else {
276 typename GridType::BBoxType bb = boundingBox(*vv);
277
278 bmin = GridType::cell(bb.min);
279 bmax = GridType::cell(bb.max);
280 }
281
282 bool found = false;
283 for (const auto& cell : GridType::cells(bmin, bmax)) {
284 found |= derived()->eraseInCell(cell, v);
285 }
286 return found;
287 }
288 return false;
289 }
290
291 bool eraseAllInCell(const KeyType& k)
292 {
293 bool res = false;
294 auto& p = derived()->valuesInCell(k);
295 // for each value contained in the cell
296 for (auto it = p.first; it != p.second; ++it) {
297 res |= derived()->eraseInCell(k, it->second);
298 }
299 return res;
300 }
301
302 // sphere operations
303 uint countInSphere(const Sphere<typename GridType::ScalarType>& s) const
304 {
305 return valuesInSphere(s).size();
306 }
307
308 // vector of iterators - return type must be auto here (we still don't know
309 // the iterator type)
310 auto valuesInSphere(const Sphere<typename GridType::ScalarType>& s) const
311 {
312 using Iter = DerivedGrid::ConstIterator;
313 using IterSet = std::set<Iter, IterComparator<Iter>>;
314
315 // will use this set only if the value type is not a point -- that is
316 // when the value can occupy more than one single cell. We therefore
317 // push the results in a set in order to avoid possible duplicates
318 IterSet valuesSet;
319
320 std::vector<Iter> resVec;
321
322 // interval of cells containing the sphere
323 KeyType first = GridType::cell(s.center() - s.radius());
324 KeyType last = GridType::cell(s.center() + s.radius());
325
326 // for each cell in the interval
327 for (const KeyType& c : GridType::cells(first, last)) {
328 // p is a pair of iterators
329 const auto& p = derived()->valuesInCell(c);
330 // for each value contained in the cell
331 for (auto it = p.first; it != p.second; ++it) {
332 if (valueIsInSpehere(it, s)) {
333 if constexpr (!PointConcept<VT> && !VertexConcept<VT>) {
334 valuesSet.insert(it);
335 }
336 else {
337 resVec.push_back(it);
338 }
339 }
340 }
341 }
342
343 // if the valuetype is a point (or vertex), we already pushed in resVec
344 // - faster than using set
345 if constexpr (!PointConcept<VT> && !VertexConcept<VT>) {
346 resVec = std::vector<Iter>(valuesSet.begin(), valuesSet.end());
347 }
348 return resVec;
349 }
350
351 void eraseInSphere(const Sphere<typename GridType::ScalarType>& s)
352 {
353 // interval of cells containing the sphere
354 KeyType first = GridType::cell(s.center() - s.radius());
355 KeyType last = GridType::cell(s.center() + s.radius());
356
357 // for each cell in the interval
358 for (const KeyType& c : GridType::cells(first, last)) {
359 // p is a pair of iterators
360 const auto& p = derived()->valuesInCell(c);
361 // for each value contained in the cell
362 for (auto it = p.first; it != p.second; ++it) {
363 if (valueIsInSpehere(it, s)) {
364 eraseInCell(it->first, it->second);
365 }
366 }
367 }
368 }
369
370 // closest queries
371 template<typename QueryValueType>
372 auto closestValue(
373 const QueryValueType& qv,
374 QueryBoundedDistFunction<QueryValueType> distFunction,
375 typename GridType::ScalarType& dist) const
376 {
377 using ScalarType = GridType::ScalarType;
378 using PointType = GridType::PointType;
379 using ResType = DerivedGrid::ConstIterator;
380
381 using QVT = RemoveCVRefAndPointer<QueryValueType>;
382 const QVT* qvv = addressOfObj(qv);
383 ResType result = derived()->end();
384
385 if (qvv) {
386 typename GridType::ScalarType maxDist = dist;
387
388 const ScalarType cellDiagonal = GridType::cellDiagonal();
389
390 // bbox of query value
391 typename GridType::BBoxType bb = boundingBox(*qvv);
392
393 ScalarType centerDist = cellDiagonal;
394 PointType center = bb.center();
395
396 // we first look just on the cells where the query value lies
397
398 // here, we will store also the looking interval where we need to
399 // look
400 Boxui currentIntervalBox;
401 Boxui lastIntervalBox = currentIntervalBox;
402 // first cell where look for closest
403 currentIntervalBox.add(GridType::cell(bb.min()));
404 // last cell where look for closest
405 currentIntervalBox.add(GridType::cell(bb.max()));
406
407 // looking just on cells where query lies
408 ScalarType tmp = cellDiagonal;
409 result = closestInCells(qv, tmp, currentIntervalBox, distFunction);
410
411 // we have found (maybe) the closest value contained in the cell(s)
412 // where the query value lies (if the cells were empty, we did not
413 // found nothing).
414
415 // if we found a value, we update the dist, which becames the
416 // max dist value. We will use it for the final search of the
417 // closest value
418 if (result != derived()->end()) {
419 dist = tmp;
420 centerDist = dist;
421 }
422 else {
423 // we did not find any value in the cells where the query value
424 // lies. We need to look in the neighborhood cells and increase
425 // the looking distance until we find a value or we reach the
426 // max distance
427
428 bool end = false;
429
430 do {
431 lastIntervalBox = currentIntervalBox;
432 currentIntervalBox.add(GridType::cell(center - centerDist));
433 currentIntervalBox.add(GridType::cell(center + centerDist));
434
435 result = closestInCells(
436 qv,
437 dist,
438 currentIntervalBox,
440 lastIntervalBox);
441
442 end = result != derived()->end();
443 end |= (centerDist > maxDist);
444 end |=
445 (center - centerDist < GridType::min() &&
446 center + centerDist > GridType::max());
447
448 // update the centerDist for the next loop (after computing
449 // the end loop condition!!)
450 centerDist += cellDiagonal;
451 } while (!end);
452 }
453
454 if (result != derived()->end()) {
455 // last check: look in all the cells inside the sphere of radius
456 // dist, in case there is a closest value
457 currentIntervalBox.add(GridType::cell(center - dist));
458 currentIntervalBox.add(GridType::cell(center + dist));
459 auto r = closestInCells(
460 qv,
461 dist,
462 currentIntervalBox,
464 lastIntervalBox);
465 if (r != derived()->end()) {
466 result = r;
467 }
468 }
469 }
470
471 return result;
472 }
473
474 template<typename QueryValueType>
475 auto closestValue(
476 const QueryValueType& qv,
477 QueryDistFunction<QueryValueType> distFunction,
478 typename GridType::ScalarType& dist) const
479 {
480 QueryBoundedDistFunction<QueryValueType> boundDistFun =
481 [&](const QueryValueType& q,
482 const RemoveCVRefAndPointer<ValueType>& v,
483 typename GridType::ScalarType) {
484 return distFunction(q, v);
485 };
486
487 dist = std::numeric_limits<typename GridType::ScalarType>::max();
488
489 return closestValue(qv, boundDistFun, dist);
490 }
491
492 template<typename QueryValueType>
493 auto closestValue(
494 const QueryValueType& qv,
495 QueryDistFunction<QueryValueType> distFunction) const
496 {
497 typename GridType::ScalarType maxDist =
498 std::numeric_limits<typename GridType::ScalarType>::max();
499 return closestValue(qv, distFunction, maxDist);
500 }
501
502 template<typename QueryValueType>
503 auto closestValue(
504 const QueryValueType& qv,
505 typename GridType::ScalarType& dist) const
506 {
507 std::function f = boundedDistFunction<
508 QueryValueType,
509 RemoveCVRefAndPointer<ValueType>,
510 typename GridType::ScalarType>();
511 return closestValue(qv, f, dist);
512 }
513
514 template<typename QueryValueType>
515 auto closestValue(const QueryValueType& qv) const
516 {
517 std::function f = boundedDistFunction<
518 QueryValueType,
519 RemoveCVRefAndPointer<ValueType>,
520 typename GridType::ScalarType>();
521 typename GridType::ScalarType maxDist =
522 std::numeric_limits<typename GridType::ScalarType>::max();
523 return closestValue(qv, f, maxDist);
524 }
525
526 template<typename QueryValueType>
527 auto kClosestValues(
528 const QueryValueType& qv,
529 uint n,
530 QueryDistFunction<QueryValueType> distFunction) const
531 {
532 using ResType = std::vector<typename DerivedGrid::ConstIterator>;
533 // KClosest Types
534 using KClosestPairType = std::pair<
535 typename GridType::ScalarType,
536 typename DerivedGrid::ConstIterator>;
537 using KClosestSet = std::
538 set<KClosestPairType, DistIterPairComparator<KClosestPairType>>;
539
540 Boxui ignore; // will contain the interval of cells already visited
541
542 KClosestSet set = valuesInCellNeighborhood(qv, n, distFunction, ignore);
543
544 auto it = set.size() >= n ? std::next(set.begin(), n - 1) : set.end();
545 // if we didn't found n values, it means that there aren't n values in
546 // the grid - nothing to do
547 if (it != set.end()) {
548 using QVT = RemoveCVRefAndPointer<QueryValueType>;
549 const QVT* qvv = addressOfObj(qv);
550
551 // bbox of query value
552 typename GridType::BBoxType bb = boundingBox(*qvv);
553 // we need to be sure that there are no values that are closest
554 // w.r.t. the n-th that we have already found by looking in the cell
555 // neighborhood. we extend the bb with the distance of the n-th
556 // closest found value
557 bb.min() -= it->first;
558 bb.max() += it->first;
559
560 // and we look in all of these cells
561 Boxui currentIntervalBox;
562 // first cell where look for closest
563 currentIntervalBox.add(GridType::cell(bb.min()));
564 // last cell where look for closest
565 currentIntervalBox.add(GridType::cell(bb.max()));
566
567 // for all the cells in the current interval box
568 for (const KeyType& c : GridType::cells(
569 currentIntervalBox.min(), currentIntervalBox.max())) {
570 if (!ignore.isInside(c)) {
571 // get the values of the cell c
572 const auto& p = derived()->valuesInCell(c);
573 // for each value contained in the cell c
574 for (auto it = p.first; it != p.second; ++it) {
575 auto tmp = distFunction(qv, dereferencePtr(it->second));
576 set.insert(std::make_pair(tmp, it));
577 }
578 }
579 }
580 }
581
582 ResType vec;
583 // if there are more than n values in the set, we will return n values,
584 // otherwise set.size()
585 uint retNValues = std::min((uint) set.size(), n);
586 vec.reserve(retNValues);
587 it = set.begin();
588 for (uint i = 0; i < retNValues; i++) {
589 vec.push_back(it->second);
590 it++;
591 }
592 return vec;
593 }
594
595 template<typename QueryValueType>
596 auto kClosestValues(const QueryValueType& qv, uint n) const
597 {
598 // get the default dist function between the query value and the
599 // elements of the grid
600 std::function f =
601 distFunction<QueryValueType, RemoveCVRefAndPointer<ValueType>>();
602 return kClosestValues(qv, n, f);
603 }
604
605protected:
611
622 const GridType& grid,
623 IntersectsCellFunction intersects = nullptr) :
624 GridType(grid), mIntersectsFun(intersects)
625 {
626 }
627
641 template<PointConcept PointType>
643 const PointType& min,
644 const PointType& max,
645 const KeyType& sizes,
646 IntersectsCellFunction intersects = nullptr) :
647 GridType(min, max, sizes), mIntersectsFun(intersects)
648 {
649 }
650
662 template<typename BoxType>
664 const BoxType& bbox,
665 const KeyType& sizes,
666 IntersectsCellFunction intersects = nullptr) :
667 GridType(bbox, sizes), mIntersectsFun(intersects)
668 {
669 }
670
691 template<typename ObjIterator>
693 ObjIterator begin,
694 ObjIterator end,
695 IntersectsCellFunction intersects = nullptr) :
696 mIntersectsFun(intersects)
697 {
698 using ScalarType = GridType::ScalarType;
699 using BBoxType = GridType::BBoxType;
700 using CellPos = GridType::CellPos;
701
702 BBoxType bbox = boundingBox(begin, end);
703 uint nElements = std::distance(begin, end);
704
705 if (nElements > 0) {
706 // inflated bb
707 ScalarType infl = bbox.diagonal() / nElements;
708 bbox.min() -= infl;
709 bbox.max() += infl;
710
711 CellPos sizes = bestGridSize(bbox.size(), nElements);
712
713 GridType::set(bbox, sizes);
714 }
715 }
716
736 template<Range Rng>
737 AbstractGrid(Rng&& r, IntersectsCellFunction intersects = nullptr) :
738 AbstractGrid(std::ranges::begin(r), std::ranges::end(r), intersects)
739 {
740 }
741
742private:
743 /* ValueType could be anything. We need to understand if it is a pointer, a
744 reference or not, in order to make proper optimized operations.
745 Therefore, we declare VT, that is used internally in this class. VT is
746 ValueType without pointers or references: */
748
749 using Boxui = Box<Point<uint, GridType::DIM>>;
750
751 template<typename Iter>
753 {
754 bool operator()(const Iter& i1, const Iter& i2) const
755 {
756 return i1->second < i2->second;
757 }
758 };
759
760 template<typename Pair>
762 {
763 bool operator()(const Pair& p1, const Pair& p2) const
764 {
765 if (p1.first == p2.first) {
766 return p1.second->second < p2.second->second;
767 }
768 return p1.first < p2.first;
769 }
770 };
771
772 DerivedGrid* derived() { return static_cast<DerivedGrid*>(this); }
773
774 const DerivedGrid* derived() const
775 {
776 return static_cast<const DerivedGrid*>(this);
777 }
778
779 // std::deque<ValueType> values;
780
785 template<typename Iterator>
787 const Iterator& it,
789 {
790 using PointType = GridType::PointType;
791
792 const VT* vv = addressOfObj(it->second);
793
794 bool test = false;
795 if constexpr (PointConcept<VT> || VertexConcept<VT>) {
796 const PointType* p;
797 if constexpr (PointConcept<VT>)
798 p = vv;
799 else
800 p = &(vv->position());
801 test = vv && s.isInside(*p);
802 }
803 else { // check if the bbox of the value intersects the sphere
804 test = vv && s.intersects(boundingBox(*vv));
805 }
806 return test;
807 }
808
814 template<typename QueryValueType>
816 const QueryValueType& qv,
817 typename GridType::ScalarType& dist,
818 const Boxui& interval,
820 const Boxui& ignore = Boxui()) const
821 {
822 using ResType = DerivedGrid::ConstIterator;
823 ResType res = derived()->end();
824
825 // for each cell in the interval
826 for (const KeyType& c :
827 GridType::cells(interval.min(), interval.max())) {
828 if (!ignore.isInsideStrict(c)) {
829 // p is a pair of iterators
830 const auto& p = derived()->valuesInCell(c);
831 // for each value contained in the cell
832 for (auto it = p.first; it != p.second; ++it) {
833 auto tmp =
834 distFunction(qv, dereferencePtr(it->second), dist);
835 if (tmp < dist) {
836 dist = tmp;
837 res = it;
838 }
839 }
840 }
841 }
842 return res;
843 }
844
845 template<typename QueryValueType>
846 auto valuesInCellNeighborhood(
847 const QueryValueType& qv,
848 uint n,
850 Boxui& ignore) const
851 {
852 // types used for K closest neighbors queries
853 using KClosestPairType = std::pair<
854 typename GridType::ScalarType,
855 typename DerivedGrid::ConstIterator>;
856 using KClosestSet = std::
857 set<KClosestPairType, DistIterPairComparator<KClosestPairType>>;
858
860
862 const QVT* qvv = addressOfObj(qv);
863
864 if (qvv) {
865 Boxui currentIntervalBox;
866 // bbox of query value
867 typename GridType::BBoxType bb = boundingBox(*qvv);
868 // first cell where look for closest
869 currentIntervalBox.add(GridType::cell(bb.min()));
870 // last cell where look for closest
871 currentIntervalBox.add(GridType::cell(bb.max()));
872
873 ignore.setNull();
874 while (res.size() < n && currentIntervalBox != ignore) {
875 // for each cell in the interval
876 for (const KeyType& c : GridType::cells(
878 if (!ignore.isInside(c)) {
879 const auto& p = derived()->valuesInCell(c);
880
881 // for each value contained in the cell
882 for (auto it = p.first; it != p.second; ++it) {
883 auto tmp =
884 distFunction(qv, dereferencePtr(it->second));
885 res.emplace(tmp, it);
886 }
887 }
888 }
889 ignore = currentIntervalBox;
890 for (uint i = 0; i < currentIntervalBox.min().DIM; ++i) {
891 if (currentIntervalBox.min()(i) != 0)
892 currentIntervalBox.min()(i)--;
893 if (currentIntervalBox.max()(i) !=
894 GridType::cellNumber(i) - 1)
895 currentIntervalBox.max()(i)++;
896 }
897 }
898 }
899
900 return res;
901 }
902};
903
904} // namespace vcl
905
906#endif // VCL_SPACE_COMPLEX_GRID_ABSTRACT_GRID_H
The AbstractGrid class describes a generic Spatial Data Structure organized on a regular grid,...
Definition abstract_grid.h:106
uint insert(Rng &&r)
Inserts all the elements contained in the input range r, from begin to end. The type referenced by th...
Definition abstract_grid.h:254
uint insert(ObjIterator begin, ObjIterator end)
Inserts all the elements from begin to end. The type referenced by the iterator must be the ValueType...
Definition abstract_grid.h:237
AbstractGrid(const GridType &grid, IntersectsCellFunction intersects=nullptr)
Creates a AbstractGrid that allows to store ValueType values on the given grid.
Definition abstract_grid.h:621
AbstractGrid()
Empty constructor, creates an usable AbstractGrid, since the Grid is not initialized.
Definition abstract_grid.h:610
AbstractGrid(ObjIterator begin, ObjIterator end, IntersectsCellFunction intersects=nullptr)
Creates an AbstractGrid having a proper Grid to store the elements.
Definition abstract_grid.h:692
bool insert(const ValueType &v)
Inserts the given element in the AbstractGrid.
Definition abstract_grid.h:181
bool valueIsInSpehere(const Iterator &it, const Sphere< typename GridType::ScalarType > &s) const
Definition abstract_grid.h:786
AbstractGrid(const BoxType &bbox, const KeyType &sizes, IntersectsCellFunction intersects=nullptr)
Creates a AbstractGrid that allows to store ValueType values on a Grid bounded by bbox,...
Definition abstract_grid.h:663
auto closestInCells(const QueryValueType &qv, typename GridType::ScalarType &dist, const Boxui &interval, QueryBoundedDistFunction< QueryValueType > distFunction, const Boxui &ignore=Boxui()) const
Definition abstract_grid.h:815
AbstractGrid(Rng &&r, IntersectsCellFunction intersects=nullptr)
Creates an AbstractGrid having a proper Grid to store the elements.
Definition abstract_grid.h:737
std::function< typename GridType::ScalarType(const QueryValueType &, const RemoveCVRefAndPointer< ValueType > &)> QueryDistFunction
The QueryDistFunction type is a std::function that takes as input a query value and a value stored in...
Definition abstract_grid.h:138
AbstractGrid(const PointType &min, const PointType &max, const KeyType &sizes, IntersectsCellFunction intersects=nullptr)
Creates a AbstractGrid that allows to store ValueType values on a Grid having min as minimum coordint...
Definition abstract_grid.h:642
std::function< bool(const typename GridType::BBoxType &, const RemoveCVRefAndPointer< ValueType > &)> IntersectsCellFunction
The IntersectsCellFunction type is a std::function that takes as input a bounding box and a value,...
Definition abstract_grid.h:117
std::function< typename GridType::ScalarType(const QueryValueType &, const RemoveCVRefAndPointer< ValueType > &, typename GridType::ScalarType)> QueryBoundedDistFunction
The QueryBoundedDistFunction type is a std::function that takes as input a query value,...
Definition abstract_grid.h:156
A class representing a box in N-dimensional space.
Definition box.h:46
auto diagonal() const
Calculates the diagonal length of the box.
Definition box.h:246
bool intersects(const Box< PointT > &b) const
Same as Box::overlap.
Definition box.h:239
bool isInsideStrict(const PointT &p) const
Checks whether a given point is inside the box or not, bounds excluded.
Definition box.h:183
PointT & max()
Returns a reference to the maximum point of the box.
Definition box.h:104
PointT & min()
Returns a reference to the minimum point of the box.
Definition box.h:90
void add(const PointT &p)
Adds the given point to the current box, expanding this box in order to contain also the values of th...
Definition box.h:385
bool isInside(const PointT &p) const
Checks whether a given point is inside the box or not, bounds included.
Definition box.h:163
PointT size() const
Computes the size of the box.
Definition box.h:267
void setNull()
Sets the Box to null. A box is considered null if at least one min component is greater than the corr...
Definition box.h:368
A concept representing a Point.
Definition point.h:843
A concept that checks whether a class has (inherits from) a Vertex class.
Definition vertex.h:80
constexpr auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:81
auto & dereferencePtr(T &&obj)
Utility function that applies the unary operator '*' to the argument only if the object is a pointer,...
Definition pointers.h:95
auto addressOfObj(T &obj)
Utility function that applies the unary operator '&' to the argument only if it is not a pointer.
Definition pointers.h:116
constexpr auto min(const T &p1, const T &p2)
Returns the minimum between the two parameters.
Definition min_max.h:40
auto boundingBox(const PointType &p)
Compute the bounding box of a single point.
Definition bounding_box.h:59
auto boundedDistFunction()
Return a proper bounded distance function between a Obj1 object and an Obj2 object.
Definition functions.h:127
auto distFunction()
Return a proper dist function between a Obj1 object and an Obj2 object.
Definition functions.h:78
Definition abstract_grid.h:762
Definition abstract_grid.h:753