OGS
Grid.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 #include <array>
18 #include <bitset>
19 #include <vector>
20 
21 #include "BaseLib/Logging.h"
22 
23 // GeoLib
24 #include "AABB.h"
25 #ifndef NDEBUG
26 #include "GEOObjects.h"
27 #endif
28 
29 namespace GeoLib
30 {
31 template <typename POINT>
32 class Grid final : public GeoLib::AABB
33 {
34 public:
51  template <typename InputIterator>
52  Grid(InputIterator first, InputIterator last,
53  std::size_t max_num_per_grid_cell = 512);
54 
59  virtual ~Grid() { delete[] _grid_cell_nodes_map; }
60 
75  template <typename P>
76  POINT* getNearestPoint(P const& pnt) const;
77 
78  template <typename P>
79  std::vector<std::size_t> getPointsInEpsilonEnvironment(P const& pnt,
80  double eps) const;
81 
93  template <typename P>
94  std::vector<std::vector<POINT*> const*>
96  double half_len) const;
97 
98  std::vector<std::vector<POINT*> const*>
100  Eigen::Vector3d const& min_pnt, Eigen::Vector3d const& max_pnt) const;
101 
102 #ifndef NDEBUG
109 #endif
110 
111 private:
125  void initNumberOfSteps(std::size_t n_per_cell, std::size_t n_pnts,
126  std::array<double, 3> const& extensions);
127 
135  template <typename T>
136  std::array<std::size_t, 3> getGridCoords(T const& pnt) const;
137 
168  template <typename P>
169  std::array<double, 6> getPointCellBorderDistances(
170  P const& pnt, std::array<std::size_t, 3> const& coords) const;
171 
172  template <typename P>
173  bool calcNearestPointInGridCell(P const& pnt,
174  std::array<std::size_t, 3> const& coords,
175  double& sqr_min_dist,
176  POINT*& nearest_pnt) const;
177 
178  static POINT* copyOrAddress(POINT& p) { return &p; }
179  static POINT const* copyOrAddress(POINT const& p) { return &p; }
180  static POINT* copyOrAddress(POINT* p) { return p; }
181 
182  std::array<std::size_t, 3> _n_steps = {{1, 1, 1}};
183  std::array<double, 3> _step_sizes = {{0.0, 0.0, 0.0}};
187  std::vector<POINT*>* _grid_cell_nodes_map = nullptr;
188 };
189 
190 template <typename POINT>
191 template <typename InputIterator>
192 Grid<POINT>::Grid(InputIterator first, InputIterator last,
193  std::size_t max_num_per_grid_cell)
194  : GeoLib::AABB(first, last)
195 {
196  auto const n_pnts(std::distance(first, last));
197 
198  auto const& max{getMaxPoint()};
199  auto const& min{getMinPoint()};
200  std::array<double, 3> delta = {
201  {max[0] - min[0], max[1] - min[1], max[2] - min[2]}};
202 
203  // enlarge delta
204  for (auto& d : delta)
205  {
206  d = std::nextafter(d, std::numeric_limits<double>::max());
207  }
208 
209  assert(n_pnts > 0);
210  initNumberOfSteps(max_num_per_grid_cell, static_cast<std::size_t>(n_pnts),
211  delta);
212 
213  const std::size_t n_plane(_n_steps[0] * _n_steps[1]);
214  _grid_cell_nodes_map = new std::vector<POINT*>[n_plane * _n_steps[2]];
215 
216  // some frequently used expressions to fill the grid vectors
217  for (std::size_t k(0); k < 3; k++)
218  {
219  if (std::abs(delta[k]) < std::numeric_limits<double>::epsilon())
220  {
221  delta[k] = std::numeric_limits<double>::epsilon();
222  }
223  _step_sizes[k] = delta[k] / _n_steps[k];
224  }
225 
226  // fill the grid vectors
227  InputIterator it(first);
228  while (it != last)
229  {
230  std::array<std::size_t, 3> coords(getGridCoords(*copyOrAddress(*it)));
231  if (coords < _n_steps)
232  {
233  std::size_t const pos(coords[0] + coords[1] * _n_steps[0] +
234  coords[2] * n_plane);
235  _grid_cell_nodes_map[pos].push_back(
236  const_cast<POINT*>(copyOrAddress(*it)));
237  }
238  else
239  {
240  ERR("Grid constructor: error computing indices [{:d}, {:d}, {:d}], "
241  "max indices [{:d}, {:d}, {:d}].",
242  coords[0], coords[1], coords[2], _n_steps[0], _n_steps[1],
243  _n_steps[2]);
244  }
245  it++;
246  }
247 }
248 
249 template <typename POINT>
250 template <typename P>
251 std::vector<std::vector<POINT*> const*>
253  double half_len) const
254 {
255  Eigen::Vector3d const c{center[0], center[1], center[2]};
256  std::array<std::size_t, 3> min_coords(getGridCoords(c.array() - half_len));
257  std::array<std::size_t, 3> max_coords(getGridCoords(c.array() + half_len));
258 
259  std::vector<std::vector<POINT*> const*> pnts;
260  pnts.reserve(
261  (Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(max_coords.data()) -
262  Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(min_coords.data()))
263  .prod());
264 
265  std::size_t const steps0_x_steps1(_n_steps[0] * _n_steps[1]);
266  for (std::size_t c0 = min_coords[0]; c0 < max_coords[0] + 1; c0++)
267  {
268  for (std::size_t c1 = min_coords[1]; c1 < max_coords[1] + 1; c1++)
269  {
270  const std::size_t coords0_p_coords1_x_steps0(c0 + c1 * _n_steps[0]);
271  for (std::size_t c2 = min_coords[2]; c2 < max_coords[2] + 1; c2++)
272  {
273  pnts.push_back(
274  &(_grid_cell_nodes_map[coords0_p_coords1_x_steps0 +
275  c2 * steps0_x_steps1]));
276  }
277  }
278  }
279  return pnts;
280 }
281 
282 template <typename POINT>
283 std::vector<std::vector<POINT*> const*>
285  Eigen::Vector3d const& min_pnt, Eigen::Vector3d const& max_pnt) const
286 {
287  std::array<std::size_t, 3> min_coords(getGridCoords(min_pnt));
288  std::array<std::size_t, 3> max_coords(getGridCoords(max_pnt));
289 
290  std::vector<std::vector<POINT*> const*> pnts;
291  pnts.reserve(
292  (Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(max_coords.data()) -
293  Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(min_coords.data()))
294  .prod());
295 
296  std::size_t const steps0_x_steps1(_n_steps[0] * _n_steps[1]);
297  for (std::size_t c0 = min_coords[0]; c0 < max_coords[0] + 1; c0++)
298  {
299  for (std::size_t c1 = min_coords[1]; c1 < max_coords[1] + 1; c1++)
300  {
301  const std::size_t coords0_p_coords1_x_steps0(c0 + c1 * _n_steps[0]);
302  for (std::size_t c2 = min_coords[2]; c2 < max_coords[2] + 1; c2++)
303  {
304  pnts.push_back(
305  &(_grid_cell_nodes_map[coords0_p_coords1_x_steps0 +
306  c2 * steps0_x_steps1]));
307  }
308  }
309  }
310  return pnts;
311 }
312 
313 #ifndef NDEBUG
314 template <typename POINT>
316 {
317  std::vector<std::string> grid_names;
318 
319  GeoLib::Point const& llf(getMinPoint());
320  GeoLib::Point const& urb(getMaxPoint());
321 
322  const double dx((urb[0] - llf[0]) / _n_steps[0]);
323  const double dy((urb[1] - llf[1]) / _n_steps[1]);
324  const double dz((urb[2] - llf[2]) / _n_steps[2]);
325 
326  // create grid names and grid boxes as geometry
327  for (std::size_t i(0); i < _n_steps[0]; i++)
328  {
329  for (std::size_t j(0); j < _n_steps[1]; j++)
330  {
331  for (std::size_t k(0); k < _n_steps[2]; k++)
332  {
333  std::string name("Grid-");
334  name += std::to_string(i);
335  name += "-";
336  name += std::to_string(j);
337  name += "-";
338  name += std::to_string(k);
339  grid_names.push_back(name);
340 
341  {
342  auto points =
343  std::make_unique<std::vector<GeoLib::Point*>>();
344  points->push_back(new GeoLib::Point(
345  llf[0] + i * dx, llf[1] + j * dy, llf[2] + k * dz));
346  points->push_back(new GeoLib::Point(llf[0] + i * dx,
347  llf[1] + (j + 1) * dy,
348  llf[2] + k * dz));
349  points->push_back(new GeoLib::Point(llf[0] + (i + 1) * dx,
350  llf[1] + (j + 1) * dy,
351  llf[2] + k * dz));
352  points->push_back(new GeoLib::Point(llf[0] + (i + 1) * dx,
353  llf[1] + j * dy,
354  llf[2] + k * dz));
355  points->push_back(new GeoLib::Point(llf[0] + i * dx,
356  llf[1] + j * dy,
357  llf[2] + (k + 1) * dz));
358  points->push_back(new GeoLib::Point(llf[0] + i * dx,
359  llf[1] + (j + 1) * dy,
360  llf[2] + (k + 1) * dz));
361  points->push_back(new GeoLib::Point(llf[0] + (i + 1) * dx,
362  llf[1] + (j + 1) * dy,
363  llf[2] + (k + 1) * dz));
364  points->push_back(new GeoLib::Point(llf[0] + (i + 1) * dx,
365  llf[1] + j * dy,
366  llf[2] + (k + 1) * dz));
367  geo_obj->addPointVec(std::move(points), grid_names.back(),
368  nullptr);
369  }
370 
371  auto plys = std::make_unique<std::vector<GeoLib::Polyline*>>();
372  auto const& points = *geo_obj->getPointVec(grid_names.back());
373  auto* ply0(new GeoLib::Polyline(points));
374 
375  for (std::size_t l(0); l < 4; l++)
376  ply0->addPoint(l);
377  ply0->addPoint(0);
378  plys->push_back(ply0);
379 
380  auto* ply1(new GeoLib::Polyline(points));
381  for (std::size_t l(4); l < 8; l++)
382  ply1->addPoint(l);
383  ply1->addPoint(4);
384  plys->push_back(ply1);
385 
386  auto* ply2(new GeoLib::Polyline(points));
387  ply2->addPoint(0);
388  ply2->addPoint(4);
389  plys->push_back(ply2);
390 
391  auto* ply3(new GeoLib::Polyline(points));
392  ply3->addPoint(1);
393  ply3->addPoint(5);
394  plys->push_back(ply3);
395 
396  auto* ply4(new GeoLib::Polyline(points));
397  ply4->addPoint(2);
398  ply4->addPoint(6);
399  plys->push_back(ply4);
400 
401  auto* ply5(new GeoLib::Polyline(points));
402  ply5->addPoint(3);
403  ply5->addPoint(7);
404  plys->push_back(ply5);
405 
406  geo_obj->addPolylineVec(std::move(plys), grid_names.back(),
407  nullptr);
408  }
409  }
410  }
411  std::string merged_geo_name("Grid");
412 
413  geo_obj->mergeGeometries(grid_names, merged_geo_name);
414 }
415 #endif
416 
417 template <typename POINT>
418 template <typename T>
419 std::array<std::size_t, 3> Grid<POINT>::getGridCoords(T const& pnt) const
420 {
421  auto const& min_point{getMinPoint()};
422  auto const& max_point{getMinPoint()};
423  std::array<std::size_t, 3> coords{0, 0, 0};
424  for (std::size_t k(0); k < 3; k++)
425  {
426  if (pnt[k] < min_point[k])
427  {
428  continue;
429  }
430  if (pnt[k] >= max_point[k])
431  {
432  coords[k] = _n_steps[k] - 1;
433  continue;
434  }
435  coords[k] = static_cast<std::size_t>(
436  std::floor((pnt[k] - min_point[k])) /
437  std::nextafter(_step_sizes[k], std::numeric_limits<double>::max()));
438  }
439  return coords;
440 }
441 
442 template <typename POINT>
443 template <typename P>
445  P const& pnt, std::array<std::size_t, 3> const& coords) const
446 {
447  auto const& min_point{getMinPoint()};
448  std::array<double, 6> dists{};
449  dists[0] =
450  std::abs(pnt[2] - min_point[2] + coords[2] * _step_sizes[2]); // bottom
451  dists[5] = std::abs(pnt[2] - min_point[2] +
452  (coords[2] + 1) * _step_sizes[2]); // top
453 
454  dists[1] =
455  std::abs(pnt[1] - min_point[1] + coords[1] * _step_sizes[1]); // front
456  dists[3] = std::abs(pnt[1] - min_point[1] +
457  (coords[1] + 1) * _step_sizes[1]); // back
458 
459  dists[4] =
460  std::abs(pnt[0] - min_point[0] + coords[0] * _step_sizes[0]); // left
461  dists[2] = std::abs(pnt[0] - min_point[0] +
462  (coords[0] + 1) * _step_sizes[0]); // right
463  return dists;
464 }
465 
466 template <typename POINT>
467 template <typename P>
469 {
470  std::array<std::size_t, 3> coords(getGridCoords(pnt));
471  auto const& min_point{getMinPoint()};
472  auto const& max_point{getMaxPoint()};
473 
474  double sqr_min_dist = (max_point - min_point).squaredNorm();
475  POINT* nearest_pnt(nullptr);
476 
477  std::array<double, 6> dists(getPointCellBorderDistances(pnt, coords));
478 
479  if (calcNearestPointInGridCell(pnt, coords, sqr_min_dist, nearest_pnt))
480  {
481  double min_dist(std::sqrt(sqr_min_dist));
482  if (dists[0] >= min_dist && dists[1] >= min_dist &&
483  dists[2] >= min_dist && dists[3] >= min_dist &&
484  dists[4] >= min_dist && dists[5] >= min_dist)
485  {
486  return nearest_pnt;
487  }
488  }
489  else
490  {
491  // search in all border cells for at least one neighbor
492  double sqr_min_dist_tmp;
493  POINT* nearest_pnt_tmp(nullptr);
494  std::size_t offset(1);
495 
496  while (nearest_pnt == nullptr)
497  {
498  std::array<std::size_t, 3> ijk{
499  {coords[0] < offset ? 0 : coords[0] - offset,
500  coords[1] < offset ? 0 : coords[1] - offset,
501  coords[2] < offset ? 0 : coords[2] - offset}};
502  for (; ijk[0] < coords[0] + offset; ijk[0]++)
503  {
504  for (; ijk[1] < coords[1] + offset; ijk[1]++)
505  {
506  for (; ijk[2] < coords[2] + offset; ijk[2]++)
507  {
508  // do not check the origin grid cell twice
509  if (ijk[0] == coords[0] && ijk[1] == coords[1] &&
510  ijk[2] == coords[2])
511  {
512  continue;
513  }
514  // check if temporary grid cell coordinates are valid
515  if (ijk[0] >= _n_steps[0] || ijk[1] >= _n_steps[1] ||
516  ijk[2] >= _n_steps[2])
517  {
518  continue;
519  }
520 
521  if (calcNearestPointInGridCell(
522  pnt, ijk, sqr_min_dist_tmp, nearest_pnt_tmp))
523  {
524  if (sqr_min_dist_tmp < sqr_min_dist)
525  {
526  sqr_min_dist = sqr_min_dist_tmp;
527  nearest_pnt = nearest_pnt_tmp;
528  }
529  }
530  } // end k
531  } // end j
532  } // end i
533  offset++;
534  } // end while
535  } // end else
536 
537  auto to_eigen = [](auto const& point)
538  { return Eigen::Map<Eigen::Vector3d const>(point.getCoords()); };
539 
540  double len((to_eigen(pnt) - to_eigen(*nearest_pnt)).norm());
541  // search all other grid cells within the cube with the edge nodes
542  std::vector<std::vector<POINT*> const*> vecs_of_pnts(
543  getPntVecsOfGridCellsIntersectingCube(pnt, len));
544 
545  const std::size_t n_vecs(vecs_of_pnts.size());
546  for (std::size_t j(0); j < n_vecs; j++)
547  {
548  std::vector<POINT*> const& pnts(*(vecs_of_pnts[j]));
549  const std::size_t n_pnts(pnts.size());
550  for (std::size_t k(0); k < n_pnts; k++)
551  {
552  const double sqr_dist(
553  (to_eigen(pnt) - to_eigen(*pnts[k])).squaredNorm());
554  if (sqr_dist < sqr_min_dist)
555  {
556  sqr_min_dist = sqr_dist;
557  nearest_pnt = pnts[k];
558  }
559  }
560  }
561 
562  return nearest_pnt;
563 }
564 
565 template <typename POINT>
566 void Grid<POINT>::initNumberOfSteps(std::size_t n_per_cell, std::size_t n_pnts,
567  std::array<double, 3> const& extensions)
568 {
569  double const max_extension(
570  *std::max_element(extensions.cbegin(), extensions.cend()));
571 
572  std::bitset<3> dim; // all bits set to zero
573  for (std::size_t k(0); k < 3; ++k)
574  {
575  // set dimension if the ratio kth-extension/max_extension >= 1e-4
576  if (extensions[k] >= 1e-4 * max_extension)
577  {
578  dim[k] = true;
579  }
580  }
581 
582  // structured grid: n_cells = _n_steps[0] * _n_steps[1] * _n_steps[2]
583  // *** condition: n_pnts / n_cells < n_per_cell
584  // => n_pnts / n_per_cell < n_cells
585  // _n_steps[1] = _n_steps[0] * extensions[1]/extensions[0],
586  // _n_steps[2] = _n_steps[0] * extensions[2]/extensions[0],
587  // => n_cells = _n_steps[0]^3 * extensions[1]/extensions[0] *
588  // extensions[2]/extensions[0],
589  // => _n_steps[0] = cbrt(n_cells * extensions[0]^2 /
590  // (extensions[1]*extensions[2]))
591  auto sc_ceil = [](double v) { return static_cast<std::size_t>(ceil(v)); };
592 
593  switch (dim.count())
594  {
595  case 3: // 3d case
596  _n_steps[0] = sc_ceil(
597  std::cbrt(n_pnts * (extensions[0] / extensions[1]) *
598  (extensions[0] / extensions[2]) / n_per_cell));
599  _n_steps[1] = sc_ceil(
600  _n_steps[0] * std::min(extensions[1] / extensions[0], 100.0));
601  _n_steps[2] = sc_ceil(
602  _n_steps[0] * std::min(extensions[2] / extensions[0], 100.0));
603  break;
604  case 2: // 2d cases
605  if (dim[0] && dim[1])
606  { // xy
607  _n_steps[0] = sc_ceil(std::sqrt(n_pnts * extensions[0] /
608  (n_per_cell * extensions[1])));
609  _n_steps[1] =
610  sc_ceil(_n_steps[0] *
611  std::min(extensions[1] / extensions[0], 100.0));
612  }
613  else if (dim[0] && dim[2])
614  { // xz
615  _n_steps[0] = sc_ceil(std::sqrt(n_pnts * extensions[0] /
616  (n_per_cell * extensions[2])));
617  _n_steps[2] =
618  sc_ceil(_n_steps[0] *
619  std::min(extensions[2] / extensions[0], 100.0));
620  }
621  else if (dim[1] && dim[2])
622  { // yz
623  _n_steps[1] = sc_ceil(std::sqrt(n_pnts * extensions[1] /
624  (n_per_cell * extensions[2])));
625  _n_steps[2] =
626  sc_ceil(std::min(extensions[2] / extensions[1], 100.0));
627  }
628  break;
629  case 1: // 1d cases
630  for (std::size_t k(0); k < 3; ++k)
631  {
632  if (dim[k])
633  {
634  _n_steps[k] =
635  sc_ceil(static_cast<double>(n_pnts) / n_per_cell);
636  }
637  }
638  }
639 }
640 
641 template <typename POINT>
642 template <typename P>
644  P const& pnt,
645  std::array<std::size_t, 3> const& coords,
646  double& sqr_min_dist,
647  POINT*& nearest_pnt) const
648 {
649  const std::size_t grid_idx(coords[0] + coords[1] * _n_steps[0] +
650  coords[2] * _n_steps[0] * _n_steps[1]);
651  std::vector<typename std::add_pointer<
652  typename std::remove_pointer<POINT>::type>::type> const&
653  pnts(_grid_cell_nodes_map[grid_idx]);
654  if (pnts.empty())
655  return false;
656 
657  auto to_eigen = [](auto const& point)
658  { return Eigen::Map<Eigen::Vector3d const>(point.getCoords()); };
659 
660  const std::size_t n_pnts(pnts.size());
661  sqr_min_dist = (to_eigen(*pnts[0]) - to_eigen(pnt)).squaredNorm();
662  nearest_pnt = pnts[0];
663  for (std::size_t i(1); i < n_pnts; i++)
664  {
665  const double sqr_dist(
666  (to_eigen(*pnts[i]) - to_eigen(pnt)).squaredNorm());
667  if (sqr_dist < sqr_min_dist)
668  {
669  sqr_min_dist = sqr_dist;
670  nearest_pnt = pnts[i];
671  }
672  }
673  return true;
674 }
675 
676 template <typename POINT>
677 template <typename P>
679  P const& pnt, double eps) const
680 {
681  std::vector<std::vector<POINT*> const*> vec_pnts(
682  getPntVecsOfGridCellsIntersectingCube(pnt, eps));
683 
684  double const sqr_eps(eps * eps);
685 
686  auto to_eigen = [](auto const& point)
687  { return Eigen::Map<Eigen::Vector3d const>(point.getCoords()); };
688 
689  std::vector<std::size_t> pnts;
690  for (auto vec : vec_pnts)
691  {
692  for (auto const p : *vec)
693  {
694  if ((to_eigen(*p) - to_eigen(pnt)).squaredNorm() <= sqr_eps)
695  {
696  pnts.push_back(p->getID());
697  }
698  }
699  }
700 
701  return pnts;
702 }
703 
704 } // end namespace GeoLib
Definition of the AABB class.
Definition of the GEOObjects class.
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition: AABB.h:49
Eigen::Vector3d const & getMinPoint() const
Definition: AABB.h:174
Eigen::Vector3d const & getMaxPoint() const
Definition: AABB.h:181
Container class for geometric objects.
Definition: GEOObjects.h:61
const std::vector< Point * > * getPointVec(const std::string &name) const
Definition: GEOObjects.cpp:71
void addPointVec(std::unique_ptr< std::vector< Point * >> points, std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> pnt_id_name_map=nullptr, double eps=std::sqrt(std::numeric_limits< double >::epsilon()))
Definition: GEOObjects.cpp:51
int mergeGeometries(std::vector< std::string > const &geo_names, std::string &merged_geo_name)
Definition: GEOObjects.cpp:435
void addPolylineVec(std::unique_ptr< std::vector< Polyline * >> lines, const std::string &name, std::unique_ptr< std::map< std::string, std::size_t >> ply_names=nullptr)
Definition: GEOObjects.cpp:150
POINT * getNearestPoint(P const &pnt) const
Definition: Grid.h:468
std::array< std::size_t, 3 > getGridCoords(T const &pnt) const
Definition: Grid.h:419
std::vector< std::vector< POINT * > const * > getPntVecsOfGridCellsIntersectingCuboid(Eigen::Vector3d const &min_pnt, Eigen::Vector3d const &max_pnt) const
Definition: Grid.h:284
static POINT * copyOrAddress(POINT &p)
Definition: Grid.h:178
static POINT * copyOrAddress(POINT *p)
Definition: Grid.h:180
std::array< double, 6 > getPointCellBorderDistances(P const &pnt, std::array< std::size_t, 3 > const &coords) const
Definition: Grid.h:444
void createGridGeometry(GeoLib::GEOObjects *geo_obj) const
Definition: Grid.h:315
bool calcNearestPointInGridCell(P const &pnt, std::array< std::size_t, 3 > const &coords, double &sqr_min_dist, POINT *&nearest_pnt) const
Definition: Grid.h:643
Grid(InputIterator first, InputIterator last, std::size_t max_num_per_grid_cell=512)
The constructor of the grid object takes a vector of points or nodes. Furthermore the user can specif...
Definition: Grid.h:192
std::vector< std::vector< POINT * > const * > getPntVecsOfGridCellsIntersectingCube(P const &center, double half_len) const
Definition: Grid.h:252
static POINT const * copyOrAddress(POINT const &p)
Definition: Grid.h:179
std::array< std::size_t, 3 > _n_steps
Definition: Grid.h:182
std::array< double, 3 > _step_sizes
Definition: Grid.h:183
std::vector< POINT * > * _grid_cell_nodes_map
Definition: Grid.h:187
virtual ~Grid()
Definition: Grid.h:59
std::vector< std::size_t > getPointsInEpsilonEnvironment(P const &pnt, double eps) const
Definition: Grid.h:678
void initNumberOfSteps(std::size_t n_per_cell, std::size_t n_pnts, std::array< double, 3 > const &extensions)
Definition: Grid.h:566
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition: Polyline.h:51
double norm(MatrixOrVector const &x, MathLib::VecNormType type)
Definition: LinAlg.h:88