Program Listing for File base_grid3D.hpp
↰ Return to documentation for file (rcppsw/ds/base_grid3D.hpp
)
#pragma once
/*******************************************************************************
* Includes
******************************************************************************/
#include <algorithm>
#include <boost/multi_array.hpp>
#include "rcppsw/common/common.hpp"
#include "rcppsw/math/vector3.hpp"
/*******************************************************************************
* Namespaces/Decls
******************************************************************************/
namespace rcppsw::ds {
/*******************************************************************************
* Class Definitions
******************************************************************************/
template <typename T>
class base_grid3D {
public:
using value_type = T;
using coord_type = rmath::vector3z;
using grid_type = typename boost::multi_array<T, 3>;
using grid_view = typename grid_type::template array_view<3>::type;
using const_grid_view = typename grid_type::template const_array_view<3>::type;
using index_range = typename grid_type::index_range;
base_grid3D(void) = default;
virtual ~base_grid3D(void) = default;
virtual T& access(size_t i, size_t j, size_t k) = 0;
virtual size_t xsize(void) const = 0;
virtual size_t ysize(void) const = 0;
virtual size_t zsize(void) const = 0;
T& access(const coord_type& c) { return access(c.x(), c.y(), c.z()); }
const T& access(const coord_type& c) const {
return const_cast<base_grid3D*>(this)->access(c);
}
const T& access(size_t i, size_t j, size_t k) const {
return const_cast<base_grid3D*>(this)->access(i, j, k);
}
bool contains(size_t i, size_t j, size_t k) {
return i < xsize() && j < ysize() && k < zsize();
}
bool contains(const coord_type& pt) {
return contains(pt.x(), pt.y(), pt.z());
}
RCPPSW_PURE T& operator[](const coord_type& c) { return access(c); }
RCPPSW_PURE const T& operator[](const coord_type& c) const {
return access(c);
}
grid_view layer(size_t z) {
return subgrid(coord_type(0, ysize(), z),
coord_type(0, ysize(), z + 1));
}
const_grid_view layer(size_t z) const {
return const_cast<base_grid3D<T>*>(this)->layer(z);
}
grid_view subgrid(const coord_type& ll, const coord_type& ur) {
index_range x(ll.x(), ur.x(), 1);
index_range y(ll.y(), ur.y(), 1);
index_range z(ll.z(), ur.z(), 1);
return grid_view(grid()[boost::indices[x][y][z]]);
}
const_grid_view subgrid(const coord_type& ll,
const coord_type& ur) const {
index_range x(ll.x(), ur.x(), 1);
index_range y(ll.y(), ur.y(), 1);
index_range z(ll.z(), ur.z(), 1);
return const_grid_view(grid()[boost::indices[x][y][z]]);
}
grid_view subcircle(const coord_type& c, size_t radius) {
auto ll_x =
std::max<int>(0, static_cast<int>(c.x()) - static_cast<int>(radius));
auto ll_y =
std::max<int>(0, static_cast<int>(c.y()) - static_cast<int>(radius));
/*
* boost uses half open interval for index ranges, and we want a closed
* interval, so we +1.
*/
auto ur_x = std::min(c.x() + radius + 1, xsize());
auto ur_y = std::min(c.y() + radius + 1, ysize());
coord_type ll(ll_x, ll_y, c.z());
coord_type ur(ur_x, ur_y, c.z() + 1);
return subgrid(ll, ur);
}
const_grid_view subcircle(const coord_type& c, size_t radius) const {
auto ll_x =
std::max<int>(0, static_cast<int>(c.x()) - static_cast<int>(radius));
auto ll_y =
std::max<int>(0, static_cast<int>(c.y()) - static_cast<int>(radius));
/*
* boost uses half open interval for index ranges, and we want a closed
* interval, so we +1.
*/
auto ur_x = std::min(c.x() + radius + 1, xsize());
auto ur_y = std::min(c.y() + radius + 1, ysize());
coord_type ll(ll_x, ll_y, c.z());
coord_type ur(ur_x, ur_y, c.z() + 1);
return subgrid(ll, ur);
}
protected:
virtual const grid_type& grid(void) const = 0;
virtual grid_type& grid(void) = 0;
};
} /* namespace rcppsw::ds */