Sign in to follow this  

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

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

If you intended to correct an error in the post then please contact us.

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[i] = array[i];
}
}

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 this post


Link to post
Share on other sites
Imagine 2D array (for simplicity) of a 3x3 elements:
123
456
789
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:
1234
5678
9000
0000


Does this explain the problem?

Share this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Spa8nky
So 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 this post


Link to post
Share on other sites
Quote:
Original post by Antheus
There 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 this post


Link to post
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];
}
}
}

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this