How to split a A*A std::array into chunks of B*B?

704 views Asked by At

if I have a std::array<std::array<int, 4>, 4> mydata, how would I split this into smaller chunks or std::array<std::array<int, 2>, 2>, so it would look like this (visually):

enter image description here

where each color is one std::array<std::array<int, 2>, 2>?

I have read some questions but they don't always ask the same or are incomplete:

Split array into chunks in C/C++ - asks how to split one continous stream of data into smaller continous bits, one dimensional

Split an image into 64x64 chunks - no source or explaination provided for ProcessChunk?

2

There are 2 answers

0
dau_sama On BEST ANSWER

The way I would do it is by not splitting the image at all.
let me elaborate:

if you create new arrays, you will have to copy the arrays over some new structure, probably std::vectors, since you don't know the different sizes at compile time.

What you can do instead, is keeping the original structure, and have a vector of Areas, where an Area is described by the 4 vertices that describe your inner square.

struct Area{
  std::pair<int,int> topleft;
  std::pair<int,int> topright;
  std::pair<int,int> bottomleft;
  std::pair<int,int> bottomright;
};

vector<Area> areas;
areas.emplace_back({0,0},{0,2},{2,0},{2,2});

If you need to use less information, you could store only two corners and compute the other two, you actually only need 4 ints to know the area.

0
ventsyv On

Write your own function to do it. It's fairly easy, something along the lines of:

Array3D splitArray(Array2D inArray, uint rows, uint cols)
{

   //Check if the array size are > 0, skipping this to save time

   //Check if the arrays 
   size_t inSize1 = inArray.size();
   size_t inSize2 = inArray[0].size();

   if rows > inSize1 || colus > inSize2 || inSize1 % rows != 0 || inSize2 % cols != 0
   {
      //throw an exception
   }

   //The arrays split requested is OK, copy the data:
   //Loop over the inArray and copy the appropriate cells in a temp 2D array
   //then add that to an array of 2D arrays:
   std::Array<Array2D> results;
   return results;
}