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++)
367 plys.push_back(ply0);
370 for (std::size_t l(4); l < 8; l++)
373 plys.push_back(ply1);
378 plys.push_back(ply2);
383 plys.push_back(ply3);
388 plys.push_back(ply4);
393 plys.push_back(ply5);
400 std::string merged_geo_name(
"Grid");
406template <
typename POINT>
412 std::array<std::size_t, 3> coords{0, 0, 0};
413 for (std::size_t k(0); k < 3; k++)
415 if (pnt[k] < min_point[k])
419 if (pnt[k] >= max_point[k])
424 coords[k] =
static_cast<std::size_t
>(
425 std::floor((pnt[k] - min_point[k]) /
427 std::numeric_limits<double>::max())));
432template <
typename POINT>
435 P
const& pnt, std::array<std::size_t, 3>
const& coords)
const
438 std::array<double, 6> dists{};
440 std::abs(pnt[2] - min_point[2] + coords[2] *
_step_sizes[2]);
441 dists[5] = std::abs(pnt[2] - min_point[2] +
445 std::abs(pnt[1] - min_point[1] + coords[1] *
_step_sizes[1]);
446 dists[3] = std::abs(pnt[1] - min_point[1] +
450 std::abs(pnt[0] - min_point[0] + coords[0] *
_step_sizes[0]);
451 dists[2] = std::abs(pnt[0] - min_point[0] +
456template <
typename POINT>
464 double sqr_min_dist = (max_point - min_point).squaredNorm();
465 POINT* nearest_pnt(
nullptr);
471 double min_dist(std::sqrt(sqr_min_dist));
472 if (dists[0] >= min_dist && dists[1] >= min_dist &&
473 dists[2] >= min_dist && dists[3] >= min_dist &&
474 dists[4] >= min_dist && dists[5] >= min_dist)
482 double sqr_min_dist_tmp;
483 POINT* nearest_pnt_tmp(
nullptr);
484 std::size_t offset(1);
486 while (nearest_pnt ==
nullptr)
488 std::array<std::size_t, 3> ijk{
489 {coords[0] < offset ? 0 : coords[0] - offset,
490 coords[1] < offset ? 0 : coords[1] - offset,
491 coords[2] < offset ? 0 : coords[2] - offset}};
492 for (; ijk[0] < coords[0] + offset; ijk[0]++)
494 for (; ijk[1] < coords[1] + offset; ijk[1]++)
496 for (; ijk[2] < coords[2] + offset; ijk[2]++)
499 if (ijk[0] == coords[0] && ijk[1] == coords[1] &&
512 pnt, ijk, sqr_min_dist_tmp, nearest_pnt_tmp))
514 if (sqr_min_dist_tmp < sqr_min_dist)
516 sqr_min_dist = sqr_min_dist_tmp;
517 nearest_pnt = nearest_pnt_tmp;
528 (pnt.asEigenVector3d() - nearest_pnt->asEigenVector3d()).norm());
530 std::vector<std::vector<POINT*>
const*> vecs_of_pnts(
533 const std::size_t n_vecs(vecs_of_pnts.size());
534 for (std::size_t j(0); j < n_vecs; j++)
536 std::vector<POINT*>
const& pnts(*(vecs_of_pnts[j]));
537 const std::size_t n_pnts(pnts.size());
538 for (std::size_t k(0); k < n_pnts; k++)
540 const double sqr_dist(
541 (pnt.asEigenVector3d() - pnts[k]->asEigenVector3d())
543 if (sqr_dist < sqr_min_dist)
545 sqr_min_dist = sqr_dist;
546 nearest_pnt = pnts[k];
554template <
typename POINT>
556 std::array<double, 3>
const& extensions)
558 double const max_extension(
559 *std::max_element(extensions.cbegin(), extensions.cend()));
562 for (std::size_t k(0); k < 3; ++k)
565 if (extensions[k] >= 1e-4 * max_extension)
580 auto sc_ceil = [](
double v) {
return static_cast<std::size_t
>(ceil(v)); };
586 std::cbrt(n_pnts * (extensions[0] / extensions[1]) *
587 (extensions[0] / extensions[2]) / n_per_cell));
589 _n_steps[0] * std::min(extensions[1] / extensions[0], 100.0));
591 _n_steps[0] * std::min(extensions[2] / extensions[0], 100.0));
594 if (dim[0] && dim[1])
596 _n_steps[0] = sc_ceil(std::sqrt(n_pnts * extensions[0] /
597 (n_per_cell * extensions[1])));
600 std::min(extensions[1] / extensions[0], 100.0));
602 else if (dim[0] && dim[2])
604 _n_steps[0] = sc_ceil(std::sqrt(n_pnts * extensions[0] /
605 (n_per_cell * extensions[2])));
608 std::min(extensions[2] / extensions[0], 100.0));
610 else if (dim[1] && dim[2])
612 _n_steps[1] = sc_ceil(std::sqrt(n_pnts * extensions[1] /
613 (n_per_cell * extensions[2])));
615 sc_ceil(std::min(extensions[2] / extensions[1], 100.0));
619 for (std::size_t k(0); k < 3; ++k)
624 sc_ceil(
static_cast<double>(n_pnts) / n_per_cell);
630template <
typename POINT>
634 std::array<std::size_t, 3>
const& coords,
635 double& sqr_min_dist,
636 POINT*& nearest_pnt)
const
638 const std::size_t grid_idx(coords[0] + coords[1] *
_n_steps[0] +
640 std::vector<
typename std::add_pointer<
641 typename std::remove_pointer<POINT>::type>::type>
const&
646 const std::size_t n_pnts(pnts.size());
648 (pnts[0]->asEigenVector3d() - pnt.asEigenVector3d()).squaredNorm();
649 nearest_pnt = pnts[0];
650 for (std::size_t i(1); i < n_pnts; i++)
652 const double sqr_dist(
653 (pnts[i]->asEigenVector3d() - pnt.asEigenVector3d()).squaredNorm());
654 if (sqr_dist < sqr_min_dist)
656 sqr_min_dist = sqr_dist;
657 nearest_pnt = pnts[i];
663template <
typename POINT>
666 P
const& pnt,
double eps)
const
668 std::vector<std::vector<POINT*>
const*> vec_pnts(
671 double const sqr_eps(eps * eps);
673 std::vector<std::size_t> pnts;
674 for (
auto vec : vec_pnts)
676 for (
auto const p : *vec)
678 if ((p->asEigenVector3d() - pnt.asEigenVector3d()).squaredNorm() <=
681 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