20template <
typename POINT>
40 template <
typename InputIterator>
41 Grid(InputIterator first, InputIterator last,
42 std::size_t max_num_per_grid_cell = 1);
86 std::vector<std::vector<POINT*>
const*>
88 double half_len)
const;
90 std::vector<std::vector<POINT*>
const*>
92 Eigen::Vector3d
const& min_pnt, Eigen::Vector3d
const& max_pnt)
const;
118 std::array<double, 3>
const& extensions);
127 template <
typename T>
160 template <
typename P>
162 P
const& pnt, std::array<std::size_t, 3>
const& coords)
const;
164 template <
typename P>
166 std::array<std::size_t, 3>
const& coords,
167 double& sqr_min_dist,
168 POINT*& nearest_pnt)
const;
182template <
typename POINT>
183template <
typename InputIterator>
185 std::size_t max_num_per_grid_cell)
188 auto const n_pnts(std::distance(first, last));
192 std::array<double, 3> delta = {
193 {max[0] - min[0], max[1] - min[1], max[2] - min[2]}};
196 constexpr double direction = std::numeric_limits<double>::max();
197 std::transform(begin(delta), end(delta), begin(delta),
198 [](
double const d) {
return std::nextafter(d, direction); });
208 for (std::size_t k(0); k < 3; k++)
210 if (std::abs(delta[k]) < std::numeric_limits<double>::epsilon())
212 delta[k] = std::numeric_limits<double>::epsilon();
218 InputIterator it(first);
224 std::size_t
const pos(coords[0] + coords[1] *
_n_steps[0] +
225 coords[2] * n_plane);
231 ERR(
"Grid constructor: error computing indices [{:d}, {:d}, {:d}], "
232 "max indices [{:d}, {:d}, {:d}].",
240template <
typename POINT>
242std::vector<std::vector<POINT*>
const*>
244 double half_len)
const
246 Eigen::Vector3d
const c{center[0], center[1], center[2]};
247 std::array<std::size_t, 3> min_coords(
getGridCoords(c.array() - half_len));
248 std::array<std::size_t, 3> max_coords(
getGridCoords(c.array() + half_len));
250 std::vector<std::vector<POINT*>
const*> pnts;
252 (Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(max_coords.data()) -
253 Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(min_coords.data()))
257 for (std::size_t c0 = min_coords[0]; c0 < max_coords[0] + 1; c0++)
259 for (std::size_t c1 = min_coords[1]; c1 < max_coords[1] + 1; c1++)
261 const std::size_t coords0_p_coords1_x_steps0(c0 + c1 *
_n_steps[0]);
262 for (std::size_t c2 = min_coords[2]; c2 < max_coords[2] + 1; c2++)
266 c2 * steps0_x_steps1]));
273template <
typename POINT>
274std::vector<std::vector<POINT*>
const*>
276 Eigen::Vector3d
const& min_pnt, Eigen::Vector3d
const& max_pnt)
const
278 std::array<std::size_t, 3> min_coords(
getGridCoords(min_pnt));
279 std::array<std::size_t, 3> max_coords(
getGridCoords(max_pnt));
281 std::vector<std::vector<POINT*>
const*> pnts;
283 (Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(max_coords.data()) -
284 Eigen::Map<Eigen::Matrix<std::size_t, 3, 1>>(min_coords.data()))
288 for (std::size_t c0 = min_coords[0]; c0 < max_coords[0] + 1; c0++)
290 for (std::size_t c1 = min_coords[1]; c1 < max_coords[1] + 1; c1++)
292 const std::size_t coords0_p_coords1_x_steps0(c0 + c1 *
_n_steps[0]);
293 for (std::size_t c2 = min_coords[2]; c2 < max_coords[2] + 1; c2++)
297 c2 * steps0_x_steps1]));
305template <
typename POINT>
308 std::vector<std::string> grid_names;
313 const double dx((urb[0] - llf[0]) /
_n_steps[0]);
314 const double dy((urb[1] - llf[1]) /
_n_steps[1]);
315 const double dz((urb[2] - llf[2]) /
_n_steps[2]);
318 for (std::size_t i(0); i <
_n_steps[0]; i++)
320 for (std::size_t j(0); j <
_n_steps[1]; j++)
322 for (std::size_t k(0); k <
_n_steps[2]; k++)
324 std::string name(
"Grid-");
325 name += std::to_string(i);
327 name += std::to_string(j);
329 name += std::to_string(k);
330 grid_names.push_back(name);
333 std::vector<GeoLib::Point*> points;
335 llf[0] + i * dx, llf[1] + j * dy, llf[2] + k * dz));
337 llf[1] + (j + 1) * dy,
340 llf[1] + (j + 1) * dy,
347 llf[2] + (k + 1) * dz));
349 llf[1] + (j + 1) * dy,
350 llf[2] + (k + 1) * dz));
352 llf[1] + (j + 1) * dy,
353 llf[2] + (k + 1) * dz));
356 llf[2] + (k + 1) * dz));
357 geo_obj->
addPointVec(std::move(points), grid_names.back());
360 std::vector<GeoLib::Polyline*> plys;
361 auto const& points = *geo_obj->
getPointVec(grid_names.back());
364 for (std::size_t l(0); l < 4; l++)
369 plys.push_back(ply0);
372 for (std::size_t l(4); l < 8; l++)
377 plys.push_back(ply1);
382 plys.push_back(ply2);
387 plys.push_back(ply3);
392 plys.push_back(ply4);
397 plys.push_back(ply5);
404 std::string merged_geo_name(
"Grid");
410template <
typename POINT>
416 std::array<std::size_t, 3> coords{0, 0, 0};
417 for (std::size_t k(0); k < 3; k++)
419 if (pnt[k] < min_point[k])
423 if (pnt[k] >= max_point[k])
428 coords[k] =
static_cast<std::size_t
>(
429 std::floor((pnt[k] - min_point[k]) /
431 std::numeric_limits<double>::max())));
436template <
typename POINT>
439 P
const& pnt, std::array<std::size_t, 3>
const& coords)
const
442 std::array<double, 6> dists{};
444 std::abs(pnt[2] - min_point[2] + coords[2] *
_step_sizes[2]);
445 dists[5] = std::abs(pnt[2] - min_point[2] +
449 std::abs(pnt[1] - min_point[1] + coords[1] *
_step_sizes[1]);
450 dists[3] = std::abs(pnt[1] - min_point[1] +
454 std::abs(pnt[0] - min_point[0] + coords[0] *
_step_sizes[0]);
455 dists[2] = std::abs(pnt[0] - min_point[0] +
460template <
typename POINT>
468 double sqr_min_dist = (max_point - min_point).squaredNorm();
469 POINT* nearest_pnt(
nullptr);
475 double min_dist(std::sqrt(sqr_min_dist));
476 if (dists[0] >= min_dist && dists[1] >= min_dist &&
477 dists[2] >= min_dist && dists[3] >= min_dist &&
478 dists[4] >= min_dist && dists[5] >= min_dist)
486 double sqr_min_dist_tmp;
487 POINT* nearest_pnt_tmp(
nullptr);
488 std::size_t offset(1);
490 while (nearest_pnt ==
nullptr)
492 std::array<std::size_t, 3> ijk{
493 {coords[0] < offset ? 0 : coords[0] - offset,
494 coords[1] < offset ? 0 : coords[1] - offset,
495 coords[2] < offset ? 0 : coords[2] - offset}};
496 for (; ijk[0] < coords[0] + offset; ijk[0]++)
498 for (; ijk[1] < coords[1] + offset; ijk[1]++)
500 for (; ijk[2] < coords[2] + offset; ijk[2]++)
503 if (ijk[0] == coords[0] && ijk[1] == coords[1] &&
516 pnt, ijk, sqr_min_dist_tmp, nearest_pnt_tmp))
518 if (sqr_min_dist_tmp < sqr_min_dist)
520 sqr_min_dist = sqr_min_dist_tmp;
521 nearest_pnt = nearest_pnt_tmp;
532 (pnt.asEigenVector3d() - nearest_pnt->asEigenVector3d()).norm());
534 std::vector<std::vector<POINT*>
const*> vecs_of_pnts(
537 const std::size_t n_vecs(vecs_of_pnts.size());
538 for (std::size_t j(0); j < n_vecs; j++)
540 std::vector<POINT*>
const& pnts(*(vecs_of_pnts[j]));
541 const std::size_t n_pnts(pnts.size());
542 for (std::size_t k(0); k < n_pnts; k++)
544 const double sqr_dist(
545 (pnt.asEigenVector3d() - pnts[k]->asEigenVector3d())
547 if (sqr_dist < sqr_min_dist)
549 sqr_min_dist = sqr_dist;
550 nearest_pnt = pnts[k];
558template <
typename POINT>
560 std::array<double, 3>
const& extensions)
562 double const max_extension(
563 *std::max_element(extensions.cbegin(), extensions.cend()));
566 for (std::size_t k(0); k < 3; ++k)
569 if (extensions[k] >= 1e-4 * max_extension)
584 auto sc_ceil = [](
double v) {
return static_cast<std::size_t
>(ceil(v)); };
590 std::cbrt(n_pnts * (extensions[0] / extensions[1]) *
591 (extensions[0] / extensions[2]) / n_per_cell));
593 _n_steps[0] * std::min(extensions[1] / extensions[0], 100.0));
595 _n_steps[0] * std::min(extensions[2] / extensions[0], 100.0));
598 if (dim[0] && dim[1])
600 _n_steps[0] = sc_ceil(std::sqrt(n_pnts * extensions[0] /
601 (n_per_cell * extensions[1])));
604 std::min(extensions[1] / extensions[0], 100.0));
606 else if (dim[0] && dim[2])
608 _n_steps[0] = sc_ceil(std::sqrt(n_pnts * extensions[0] /
609 (n_per_cell * extensions[2])));
612 std::min(extensions[2] / extensions[0], 100.0));
614 else if (dim[1] && dim[2])
616 _n_steps[1] = sc_ceil(std::sqrt(n_pnts * extensions[1] /
617 (n_per_cell * extensions[2])));
619 sc_ceil(std::min(extensions[2] / extensions[1], 100.0));
623 for (std::size_t k(0); k < 3; ++k)
628 sc_ceil(
static_cast<double>(n_pnts) / n_per_cell);
634template <
typename POINT>
638 std::array<std::size_t, 3>
const& coords,
639 double& sqr_min_dist,
640 POINT*& nearest_pnt)
const
642 const std::size_t grid_idx(coords[0] + coords[1] *
_n_steps[0] +
644 std::vector<
typename std::add_pointer<
645 typename std::remove_pointer<POINT>::type>::type>
const&
652 const std::size_t n_pnts(pnts.size());
654 (pnts[0]->asEigenVector3d() - pnt.asEigenVector3d()).squaredNorm();
655 nearest_pnt = pnts[0];
656 for (std::size_t i(1); i < n_pnts; i++)
658 const double sqr_dist(
659 (pnts[i]->asEigenVector3d() - pnt.asEigenVector3d()).squaredNorm());
660 if (sqr_dist < sqr_min_dist)
662 sqr_min_dist = sqr_dist;
663 nearest_pnt = pnts[i];
669template <
typename POINT>
672 P
const& pnt,
double eps)
const
674 std::vector<std::vector<POINT*>
const*> vec_pnts(
677 double const sqr_eps(eps * eps);
679 std::vector<std::size_t> pnts;
680 for (
auto vec : vec_pnts)
682 for (
auto const p : *vec)
684 if ((p->asEigenVector3d() - pnt.asEigenVector3d()).squaredNorm() <=
687 pnts.push_back(p->getID());
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Eigen::Vector3d const & getMaxPoint() const
AABB(std::vector< PNT_TYPE * > const &pnts, std::vector< std::size_t > const &ids)
Eigen::Vector3d const & getMinPoint() const
MinMaxPoints getMinMaxPoints() const
Container class for geometric objects.
void addPolylineVec(std::vector< Polyline * > &&lines, std::string const &name, PolylineVec::NameIdMap &&ply_names)
const std::vector< Point * > * getPointVec(const std::string &name) const
void addPointVec(std::vector< Point * > &&points, std::string &name, PointVec::NameIdMap &&pnt_id_name_map, double const eps=std::sqrt(std::numeric_limits< double >::epsilon()))
int mergeGeometries(std::vector< std::string > const &geo_names, std::string &merged_geo_name)
std::vector< std::vector< POINT * > const * > getPntVecsOfGridCellsIntersectingCuboid(Eigen::Vector3d const &min_pnt, Eigen::Vector3d const &max_pnt) const
POINT * getNearestPoint(P const &pnt) const
std::array< std::size_t, 3 > getGridCoords(T const &pnt) const
static POINT * copyOrAddress(POINT &p)
Grid(Grid const &)=delete
static POINT const * copyOrAddress(POINT const &p)
std::array< double, 6 > getPointCellBorderDistances(P const &pnt, std::array< std::size_t, 3 > const &coords) const
std::vector< std::vector< POINT * > const * > getPntVecsOfGridCellsIntersectingCube(P const ¢er, double half_len) const
void createGridGeometry(GeoLib::GEOObjects *geo_obj) const
bool calcNearestPointInGridCell(P const &pnt, std::array< std::size_t, 3 > const &coords, double &sqr_min_dist, POINT *&nearest_pnt) const
std::array< std::size_t, 3 > _n_steps
std::array< double, 3 > _step_sizes
std::vector< POINT * > * _grid_cell_nodes_map
Grid & operator=(Grid const &)=delete
Grid(InputIterator first, InputIterator last, std::size_t max_num_per_grid_cell=1)
The constructor of the grid object takes a vector of points or nodes. Furthermore the user can specif...
static POINT * copyOrAddress(POINT *p)
std::vector< std::size_t > getPointsInEpsilonEnvironment(P const &pnt, double eps) const
void initNumberOfSteps(std::size_t n_per_cell, std::size_t n_pnts, std::array< double, 3 > const &extensions)
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
std::map< std::string, std::size_t > NameIdMap