// Class representing 2D grid of points in 3D. #ifndef GRID2D_POINTS3D_H #define GRID2D_POINTS3D_H #include #include #include #include #include // ******************************************************************************** // 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>> 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>( 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 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(toupper( static_cast(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 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