39 bool forwardOnly =
false;
41 std::vector<int> offsetRow;
42 std::vector<int> offsetCol;
43 std::vector<uint8_t> forwardMask;
56 this->numRows = numRows;
57 this->numCols = numCols;
58 this->radius = radius;
59 this->radius2 = radius * radius;
71 this->offsetCol.resize(this->n);
72 this->offsetRow.resize(this->n);
77 this->offsetCol[
i] =
dx;
78 this->offsetRow[
i] =
dy;
79 if ((
dx == 0) && (
dy == 0))
87 std::vector<float>
da(n);
88 std::vector<float>
dr(n);
91 for (
i = 0;
i < n;
i++) {
92 dx = this->offsetCol[
i];
93 dy = this->offsetRow[
i];
96 da[
i] = (std::atan2(-
dy, -
dx) * 180.0 / std::numbers::pi);
114 auxX = this->offsetCol[
i0];
115 auxY = this->offsetRow[
i0];
116 this->offsetCol[
i0] = this->offsetCol[0];
117 this->offsetRow[
i0] = this->offsetRow[0];
119 this->offsetCol[0] =
auxX;
120 this->offsetRow[0] =
auxY;
124 for (
i = 1;
i < n - 1;
i++) {
126 for (
j =
i + 1;
j < n;
j++)
137 auxX = this->offsetCol[
i];
138 auxY = this->offsetRow[
i];
139 this->offsetCol[
i] = this->offsetCol[
k];
140 this->offsetRow[
i] = this->offsetRow[
k];
142 this->offsetCol[
k] =
auxX;
143 this->offsetRow[
k] =
auxY;
147 for (
i = 1;
i < n - 1;
i++) {
149 for (
j =
i + 1;
j < n;
j++)
157 auxX = this->offsetCol[
i];
158 auxY = this->offsetRow[
i];
159 this->offsetCol[
i] = this->offsetCol[
k];
160 this->offsetRow[
i] = this->offsetRow[
k];
162 this->offsetCol[
k] =
auxX;
163 this->offsetRow[
k] =
auxY;
168 forwardMask.resize(n, 0);
169 for (
int k = 1;
k < n; ++
k) {
170 int dx = offsetCol[
k],
dy = offsetRow[
k];
171 forwardMask[
k] = (
dy > 0 || (
dy == 0 &&
dx > 0)) ? 1 : 0;
186 if (forwardOnly && !forwardMask[
id]) {
id += 1;
continue; }
189 const int newRow = row + offsetRow[id];
190 const int newCol = col + offsetCol[id];
233 throw std::out_of_range(
"Index out of bounds.");
238 this->forwardOnly =
false;
265 throw std::out_of_range(
"Index out of bounds.");
270 this->forwardOnly =
false;
298 throw std::out_of_range(
"Index out of bounds.");
303 this->forwardOnly =
true;
326 int py =
p / numCols,
px =
p % numCols;
327 int qy =
q / numCols,
qx =
q % numCols;
379 return row == 0 || col == 0 || row == this->numRows - 1 || col == this->numCols - 1;
388 return offsetRow[index];
397 return offsetCol[index];
444 return index ==
other.index;
451 return !(*
this ==
other);
458 return (instance->row + instance->offsetRow[index]) * instance->numCols + (instance->col + instance->offsetCol[index]);
Contiguous row-major image container and coordinate helpers.
Lightweight iterator over the currently configured traversal.
IteratorAdjacency(AdjacencyRelation *obj, int id)
Creates an iterator over obj at stencil position id.
bool operator!=(const IteratorAdjacency &other) const
Returns true when the iterators point to different stencil positions.
bool operator==(const IteratorAdjacency &other) const
Returns true when both iterators point to the same stencil position.
IteratorAdjacency & operator++()
Advances to the next valid neighbour in the current traversal.
int operator*() const
Returns the current neighbour as a linear pixel index.
std::input_iterator_tag iterator_category
Input-iterator category for range-based traversal.
AdjacencyRelation * getInstance()
Returns the adjacency relation currently being traversed.
Two-dimensional adjacency relation with configurable radius and efficient iteration.
bool isBorderDomainImage(int row, int col)
Returns whether (row, col) lies on the image border.
IteratorAdjacency begin()
Returns the beginning of the current traversal.
bool isAdjacent(int px, int py, int qx, int qy) const noexcept
Tests adjacency between two pixel coordinates.
int getOffsetRow(int index)
Returns the row offset stored at stencil position index.
int getOffsetCol(int index)
Returns the column offset stored at stencil position index.
AdjacencyRelation(int numRows, int numCols, double radius)
Builds an adjacency relation for a numRows by numCols image.
AdjacencyRelation & getNeighborPixels(int row, int col)
Prepares iteration over valid neighbouring pixels, excluding the origin.
bool isAdjacent(int p, int q) const noexcept
Tests adjacency between two linear pixel indices.
double getRadius() const
Returns the configured neighbourhood radius.
AdjacencyRelation & getNeighborPixels(int indexVector)
Prepares iteration over valid neighbouring pixels from a linear index, excluding the origin.
IteratorAdjacency end()
Returns the end sentinel of the current traversal.
int getNumCols() const noexcept
Returns the number of columns in the attached image domain.
int nextValid()
Advances to the next valid offset under the current bounds and mode.
AdjacencyRelation & getNeighborPixelsForward(int row, int col)
Prepares forward-only neighbour iteration at (row, col).
bool is8connectivity() const
Returns true when the stencil represents 8-connectivity.
bool is4connectivity() const
Returns true when the stencil represents 4-connectivity.
AdjacencyRelation & getAdjPixels(int indexVector)
Prepares iteration over adjacent pixels from a linear index, including the origin.
int getNumRows() const noexcept
Returns the number of rows in the attached image domain.
AdjacencyRelation & getAdjPixels(int row, int col)
Prepares iteration over adjacent pixels, including the origin.
AdjacencyRelation & getNeighborPixelsForward(int indexVector)
Prepares forward-only neighbour iteration from a linear index.
bool isBorderDomainImage(int index)
Returns whether a linear pixel index lies on the image border.
int getSize() const
Returns the number of offsets in the current stencil.
static std::pair< int, int > to2D(int index, int numCols) noexcept
Converts a row-major linear index to (row, col).
Owning result for one computed scalar attribute layout and buffer.