Visual Computing Library
Loading...
Searching...
No Matches
regular_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_REGULAR_GRID_H
24#define VCL_SPACE_COMPLEX_GRID_REGULAR_GRID_H
25
26#include "iterators/cell_iterator.h"
27
28#include <vclib/space/core/box.h>
29#include <vclib/types/view.h>
30
31namespace vcl {
32
33template<typename Scalar, int N>
35{
36 static_assert(
37 N > 0,
38 "Number of dimensions of the regular grid must be > 1.");
39
40public:
43
44private:
45 BBoxType mBBox;
46 Point<uint, N> mSize;
47
48public:
49 static const int DIM = N;
50 using ScalarType = Scalar;
52
55
56 RegularGrid() = default;
57
59 const Point<Scalar, N>& min,
60 const Point<Scalar, N>& max,
61 const Point<uint, N>& size) : mBBox(min, max), mSize(size)
62 {
63 }
64
65 RegularGrid(const Box<Point<Scalar, N>>& bbox, const Point<uint, N>& size) :
66 mBBox(bbox), mSize(size)
67 {
68 }
69
70 Point<Scalar, N> min() const { return mBBox.min(); }
71
72 Point<Scalar, N> max() const { return mBBox.max(); }
73
79 Scalar length(uint d) const { return mBBox.dim(d); }
80
86 {
88 for (size_t i = 0; i < DIM; ++i)
89 p(i) = length(i);
90 return p;
91 }
92
98 uint cellNumber(uint d) const { return mSize(d); }
99
104 Point<uint, N> cellNumbers() const { return mSize; }
105
112 uint indexOfCell(const CellCoord& c) const
113 {
114 unsigned long int ind = c[0];
115 assert(c[0] < mSize[0]);
116 for (unsigned int i = 1; i < N; i++) {
117 assert(c[i] < mSize[i]);
118 ind *= mSize[i];
119 ind += c[i];
120 }
121 return ind;
122 }
123
129 CellCoord cellOfIndex(uint index) const
130 {
132 for (long int i = N - 1; i >= 0; i--) {
133 c[i] = index % mSize[i];
134 index /= mSize[i];
135 }
136 return c;
137 }
138
144 Scalar cellLength(uint d) const { return length(d) / cellNumber(d); }
145
151 {
153 for (size_t i = 0; i < DIM; ++i)
154 p(i) = cellLength(i);
155 return p;
156 }
157
158 Scalar cellDiagonal() const { return cellLengths().norm(); }
159
160 uint cell(uint d, const Scalar& s) const
161 {
162 if (s < mBBox.min()(d))
163 return 0;
164 if (s > mBBox.max()(d))
165 return cellNumber(d) - 1;
166 Scalar t = s - mBBox.min()(d);
167 return uint(t / cellLength(d));
168 }
169
170 CellCoord cell(const Point<Scalar, N>& p) const
171 {
172 CellCoord c;
173 for (size_t i = 0; i < DIM; ++i)
174 c(i) = cell(i, p(i));
175 return c;
176 }
177
178 Point<Scalar, N> cellLowerCorner(const CellCoord& c) const
179 {
180 Point<Scalar, N> l;
181 for (size_t i = 0; i < DIM; ++i)
182 l(i) = min(i) + c(i) * cellLength(i); // cellLowerCorner(i, c(i));
183 return l;
184 }
185
186 BBoxType cellBox(const CellCoord& c) const
187 {
188 BBoxType b;
189
190 Point<Scalar, N> p;
191 for (size_t i = 0; i < DIM; ++i)
192 p(i) = (Scalar) c(i) * cellLength(i);
193 p += mBBox.min();
194 b.min() = p;
195 b.max() = (p + cellLengths());
196
197 return b;
198 }
199
200 CellIterator cellBegin() const { return CellIterator(CellCoord(), mSize); }
201
202 CellIterator cellBegin(const CellCoord& first, const CellCoord& last) const
203 {
204 return CellIterator(first, last + 1);
205 }
206
207 CellIterator cellEnd() const { return CellIterator(); }
208
209 CellView cells() const { return CellView(cellBegin(), cellEnd()); }
210
211 CellView cells(const CellCoord& first, const CellCoord& last) const
212 {
213 return CellView(cellBegin(first, last), cellEnd());
214 }
215
216protected:
217 void set(const Box<Point<Scalar, N>>& box, const Point<uint, N>& size)
218 {
219 mBBox = box;
220 mSize = size;
221 }
222};
223
224/* Specialization Aliases */
225
226template<typename Scalar>
227using RegularGrid2 = RegularGrid<Scalar, 2>;
228
229template<typename Scalar>
230using RegularGrid3 = RegularGrid<Scalar, 3>;
231
232/* Deduction guides */
233
234template<PointConcept PointType, typename D>
235RegularGrid(PointType, PointType, D)
236 -> RegularGrid<typename PointType::ScalarType, PointType::DIM>;
237
238/* Regular Grid related functions */
239
249template<PointConcept PointType>
250Point<uint, PointType::DIM> bestGridSize(
251 const PointType& lengths,
252 uint nElements)
253{
254 using Scalar = PointType::ScalarType;
255
256 static const int DIM = PointType::DIM;
257
258 const uint mincells = 1; // Numero minimo di celle
259 const Scalar GFactor = 1; // GridEntry = NumElem*GFactor
260 const Scalar diag = lengths.norm(); // Diagonale del box
261 const Scalar eps = diag * 1e-4; // Fattore di tolleranza
262 const uint ncell = nElements * GFactor; // Calcolo numero di voxel
263
264 Point<uint, PointType::DIM> sizes;
265 sizes.setConstant(mincells);
266
267 bool sanityCheckLengths = true;
268 uint lessEpsDimNumber = 0;
269 std::array<bool, DIM> isLessEps;
270
271 for (uint i = 0; i < DIM; i++) {
272 sanityCheckLengths = sanityCheckLengths && lengths(i) > 0.0;
273 if (lengths(i) < eps) {
274 lessEpsDimNumber++;
275 isLessEps[i] = true;
276 }
277 }
278 uint greaterEpsDimNumber = DIM - lessEpsDimNumber;
279
280 if (nElements > 0 && sanityCheckLengths) {
281 // no lenghts less than epsilon - standard computation for sizes
282 if (greaterEpsDimNumber == DIM) {
283 Scalar product = 1;
284 for (uint i = 0; i < DIM; i++)
285 product *= lengths(i);
286
287 Scalar k = std::pow((ncell / product), (1.0 / DIM));
288
289 for (uint i = 0; i < DIM; i++)
290 sizes(i) = int(lengths(i) * k);
291 }
292 // at least one lenght is less than epsilon
293 else {
294 for (uint i = 0; i < DIM; i++) {
295 if (isLessEps[i]) { // the ith dimension is less than epsilon
296 sizes(i) = 1;
297 }
298 else {
299 // compute the product between all the dimensions that are
300 // not i and not less than epsilon
301 Scalar product = 1;
302 for (uint j = 0; j < DIM; j++)
303 if (j != i && !isLessEps[j])
304 product *= lengths(j);
305
306 // ith dimension size
307 sizes(i) = std::pow(
308 (ncell * lengths(i) / product),
309 (1.0 / greaterEpsDimNumber));
310 }
311 }
312 }
313
314 for (uint i = 0; i < DIM; i++)
315 sizes(i) = std::max(sizes(i), (uint) 1);
316 }
317
318 return sizes;
319}
320
321} // namespace vcl
322
323#endif // VCL_SPACE_COMPLEX_GRID_REGULAR_GRID_H
PointT & max()
Returns a reference to the maximum point of the box.
Definition box.h:107
PointT & min()
Returns a reference to the minimum point of the box.
Definition box.h:93
auto dim(uint i) const
Get the length of the box along a given dimension.
Definition box.h:295
Definition regular_grid.h:35
Point< Scalar, N > lengths() const
Returns the edge legths of the bounding box of the grid.
Definition regular_grid.h:85
uint indexOfCell(const CellCoord &c) const
Return an unique index that can be associated to the given cell coordinate.
Definition regular_grid.h:112
Scalar cellLength(uint d) const
Returns the length of a cell of the grid in the d-th dimension.
Definition regular_grid.h:144
Scalar length(uint d) const
Returns the edge legth of the bounding box of the grid in the d-th dimension.
Definition regular_grid.h:79
uint cellNumber(uint d) const
Returns the number of cells of the Grid in the d-th dimension.
Definition regular_grid.h:98
Point< uint, N > cellNumbers() const
Returns the number of cells for each dimension of the grid.
Definition regular_grid.h:104
Point< Scalar, N > cellLengths() const
Returns the lengths of a cell of the grid for each dimension.
Definition regular_grid.h:150
CellCoord cellOfIndex(uint index) const
Returns the cell coordinate associated to the given unique index.
Definition regular_grid.h:129
A class representing a line segment in n-dimensional space. The class is parameterized by a PointConc...
Definition segment.h:43
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