guassmith guassmith - 1 month ago 10
C++ Question

How to change the xyz order when using a flattened 3D array

I'm using a flattened 3d array for my program, and from everything I've read, the way to access it is:

array[x + width * (y + depth * z)]

This is the equivalent of
array[x][y][z]


Unfortunately in my code I need to use
array[x][z][y]
Does anyone know how to change the flattened formula from xyz to xzy?

yzt yzt
Answer

As long as you stay consistent in accessing the array, you can access it however you like. A "flattened" 3D array is just a normal array now, and the indices has absolutely no meaning for the system. The only meaning is what you assign to them in your mind.

Therefore, it is perfectly OK to imagine the array to be - as you put it - an XZY array instead of an XYZ array, or any other permutation of the indices. The general formula is (when you are imagining the array to be a flattened 3D array):

FlatIndex(1st, 2nd, 3rd) = 1st * PlaneSize + 2nd * RowSize + 3rd;

where RowSize is obviously the number of elements in a row (i.e. the number of elements in the 3rd dimension) and PlaneSize is the number of elements in a plane, or the number of elements in a row times the number of rows there is.

Deriving the above formula is simple: if you think about how the elements are put beside each other, you will see that when you increment the 3rd index by 1, you increase its "address" by 1 as well (address means where it is in the 1D array) hence the fact that the 3rd index has a coefficient of 1. When you increase the 2nd index by 1, you are effectively going to the next row, and your address in increased by a row's worth of elements at once. In other words, an increment of 1 for the 2nd index is the same as an increment equal to the size of a row for the 3rd index, therefore the 2nd index has a coefficient of RowSize. The same goes for the 1st index.

If we had any number of indices (i.e. a flattened N-dimensional array,) the reasoning would have been the same.

But this is all imaginary. You can devise any "mapping" function between the three indices used in a 3D array and the single index used in a normal 1D array (with some restrictions; e.g. it must cover all your domain, and it must be reversible.) The formula everybody uses though is a pretty good one: it's fast to compute, it's 1-to-1 which means it uses all the entries in the 1D array and leaves no holes (i.e. wastes no memory,) etc.

As long as you are consistent in use of your mapping function (in all its aspects, including the order of indices) everywhere you access the same array, you'll be fine.