137 lines
4.0 KiB
C++
137 lines
4.0 KiB
C++
// Class representing 2D grid of points in 3D.
|
|
|
|
#ifndef GRID2D_POINTS3D_H
|
|
#define GRID2D_POINTS3D_H
|
|
|
|
#include <array>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
|
|
// ********************************************************************************
|
|
// Class GRID2D_POINTS3D
|
|
// ********************************************************************************
|
|
|
|
/// A class to store a 2D grid of 3D points.
|
|
class GRID2D_POINTS3D {
|
|
|
|
public:
|
|
|
|
static const int DIM3 = 3;
|
|
|
|
int num_rows;
|
|
int num_cols;
|
|
|
|
/// coord[i][j] = {x, y, z} for grid point at row i, column j.
|
|
std::vector<std::vector<std::array<double, 3>>> coord;
|
|
|
|
bool are_dimensions_set;
|
|
|
|
|
|
GRID2D_POINTS3D() :
|
|
num_rows(0), num_cols(0), are_dimensions_set(false) {}
|
|
|
|
|
|
void SetDimensions(int n, int m) {
|
|
num_rows = n;
|
|
num_cols = m;
|
|
coord.assign(n, std::vector<std::array<double, 3>>(
|
|
m, {0.0, 0.0, 0.0}));
|
|
are_dimensions_set = true;
|
|
}
|
|
|
|
bool AreDimensionsSet() const {
|
|
return are_dimensions_set;
|
|
}
|
|
|
|
int NumRows() const { return num_rows; }
|
|
|
|
int NumCols() const { return num_cols; }
|
|
|
|
int NumPoints() const { return num_rows * num_cols; }
|
|
|
|
int NumQuadrilaterals() const {
|
|
if (num_rows < 2 || num_cols < 2) { return 0; }
|
|
return (num_rows - 1) * (num_cols - 1);
|
|
}
|
|
|
|
int PointDimension() const { return DIM3; }
|
|
|
|
/// Index of point (irow, icol) in a flat array.
|
|
/// k'th point in array coord has index (k-1).
|
|
int PointIndex(int irow, int icol) const {
|
|
return irow * NumCols() + icol;
|
|
}
|
|
|
|
/// Return false and error message if (index < 0) or (index >= iupper).
|
|
std::pair<bool, std::string> CheckIndex(
|
|
int index, int iupper,
|
|
const std::string& index_name) const
|
|
{
|
|
if (index < 0) {
|
|
return {false,
|
|
"Illegal negative " + index_name + " index " +
|
|
std::to_string(index) + "."};
|
|
}
|
|
|
|
if (index >= iupper) {
|
|
std::string name = index_name;
|
|
name[0] = static_cast<char>(toupper(
|
|
static_cast<unsigned char>(name[0])));
|
|
return {false,
|
|
name + " " + std::to_string(index) +
|
|
" is out of bounds.\n" +
|
|
" " + name + " index should be less than " +
|
|
std::to_string(iupper) + "."};
|
|
}
|
|
|
|
return {true, ""};
|
|
}
|
|
|
|
/// Raise std::out_of_range if (index < 0) or (index >= iupper).
|
|
void CheckIndexRaiseError(
|
|
int index, int iupper,
|
|
const std::string& index_name,
|
|
const std::string& function_name) const
|
|
{
|
|
auto result = CheckIndex(index, iupper, index_name);
|
|
if (!result.first) {
|
|
throw std::out_of_range(
|
|
"Error in GRID2D_POINTS3D::" + function_name +
|
|
". " + result.second);
|
|
}
|
|
}
|
|
|
|
/// Return coordinates of grid point [irow][jcol].
|
|
/// Precondition: [irow][jcol] are in appropriate bounds.
|
|
std::array<double, 3> Coord(int irow, int jcol) const {
|
|
return coord[irow][jcol];
|
|
}
|
|
|
|
/// Set coord[irow][jcol] to (x, y, z).
|
|
void SetCoord(int irow, int jcol, double x, double y, double z) {
|
|
CheckIndexRaiseError(irow, NumRows(), "Row", "SetCoord");
|
|
CheckIndexRaiseError(jcol, NumCols(), "Column", "SetCoord");
|
|
coord[irow][jcol] = {x, y, z};
|
|
}
|
|
|
|
/// Print grid in formatted mode. Mainly for debugging.
|
|
void FormattedPrint() const {
|
|
std::cout << "Grid dimensions: " << num_rows << " x "
|
|
<< num_cols << "\n";
|
|
std::cout << "Point Coordinates:\n";
|
|
for (int i = 0; i < num_rows; i++) {
|
|
for (int j = 0; j < num_cols; j++) {
|
|
std::cout << " [" << i << "][" << j << "]: "
|
|
<< coord[i][j][0] << " "
|
|
<< coord[i][j][1] << " "
|
|
<< coord[i][j][2] << "\n";
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif // GRID2D_POINTS3D_H
|