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