# [C#] Extending a 1D array gives incorrect results when accessed as 3D array

This topic is 2968 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

If I have an array:

int[] array = new int[]

I can then access the array like a 3D array using:

int index = x * width * height + y * width + z;array[index]

The problem is that when I extend an array dimension (in this case the width) using the following set property:

                width = value;                // Create a temporary array using the new dimensions                int[] tempArray = new int[depth * height * width];                if (width > oldWidth)                {                    // Copy the current tiles to that array                    array.CopyTo(tempArray, 0);                }                else                {                    for (int i = 0; i < tempArray.Length; ++i)                    {                        tempArray = array;                    }                }                array = tempArray;

the indices of the elements are no longer valid.

How can I adjust a dimension of the 1D array and assign the original elements so they can be accessed in the same way?

##### Share on other sites
Imagine 2D array (for simplicity) of a 3x3 elements:
123456789
When written as 1D array, it looks like this:
123456789

When such an array is resized to 4x4, using the algorithm above, the 1D array looks like this:
123456789000000

If this is displayed as 2D array, it looks like this:
1234567890000000

Does this explain the problem?

##### Share on other sites
That explains the problem I am having perfectly.

So I need to find a way to copy the old dimensional structure to the new dimensions... Is this method over the top?

                // Create a temporary array using the new dimensions                int[] tempArray = new int[width * height * depth];                for (int x = 0; x < depth; ++x)                {                    for (int y = 0; y < height; ++y)                    {                        for (int z = 0; z < oldWidth; ++z)                        {                            int i0 = x * width * height + y * width + z;                            int i1 = x * oldWidth * height + y * oldWidth + z;                            tempArray[i0] = array[i1];                        }                    }                }

##### Share on other sites
Quote:
 Original post by Spa8nkySo I need to find a way to copy the old dimensional structure to the new dimensions... Is this method over the top?

It's straightforward. A "more efficient" algorithm would be possible, but those quickly become convoluted.

 int i1 = x * oldWidth * height + y * oldWidth + z;
height should be oldHeight.

for (int y = 0; y < height; ++y)
Same here.

There is no reason to write same algorithm for each of dimensions being changed.

##### Share on other sites
Quote:
 Original post by AntheusThere is no reason to write same algorithm for each of dimensions being changed.

Something like this method then:

        private void Resize(int oldWidth, int oldHeight, int oldDepth, int width, int height, int depth)        {            // Create a temporary array using the new dimensions            int[] tempArray = new int[width * height * depth];            for (int x = 0; x < oldDepth; ++x)            {                for (int y = 0; y < oldHeight; ++y)                {                    for (int z = 0; z < oldWidth; ++z)                    {                        int i0 = x * width * height + y * width + z;                        int i1 = x * oldWidth * oldHeight + y * oldWidth + z;                        tempArray[i0] = array[i1];                    }                }            }            array = tempArray;        }

Shouldn't I add the following lines to the top of the method to handle cases where the new dimension is smaller than the old one?

            oldDepth = Math.Min(oldDepth, depth);            oldHeight = Math.Min(oldHeight, height);            oldWidth = Math.Min(oldWidth, width);

##### Share on other sites
That would cause "int i1 = x * oldWidth * oldHeight + y * oldWidth + z;" to be the wrong index again. You just want to clamp the region you are looping over, nothing else.

##### Share on other sites
Like so?

            int xEnd = Math.Min(oldDepth, depth);            int yEnd = Math.Min(oldHeight, height);            int zEnd = Math.Min(oldWidth, width);            // Create a temporary array using the new dimensions            int[] tempArray = new Tile3D[width * height * depth];            for (int x = 0; x < xEnd; ++x)            {                for (int y = 0; y < yEnd; ++y)                {                    for (int z = 0; z < zEnd; ++z)                    {                        int i0 = x * width * height + y * width + z;                        int i1 = x * oldWidth * oldHeight + y * oldWidth + z;                        tempArray[i0] = array[i1];                    }                }            }

1. 1
Rutin
25
2. 2
3. 3
4. 4
5. 5

• 10
• 13
• 19
• 14
• 9
• ### Forum Statistics

• Total Topics
632942
• Total Posts
3009343
• ### Who's Online (See full list)

There are no registered users currently online

×