Hi there,
Texture2D’s GetPixels method returns Flattened 2D Array which is a bit over my head.
What i want to do is iterate on that array column wise. From top to Bottom, then next colum top to bottom and so on.
Please advise
Thanks
Hi there,
Texture2D’s GetPixels method returns Flattened 2D Array which is a bit over my head.
What i want to do is iterate on that array column wise. From top to Bottom, then next colum top to bottom and so on.
Please advise
Thanks
You can transform a 2D position to a 1D index like this;
int GetIndex(int x, int y, int dimension)
{
return x + y * dimension;
}
Dimension is the width or height of a square texture.
So for example, if your texture is 10x10 pixels and your inputs are (x2, y3) then the index will be 2 + 3 * 10 = 32.
Grizzly has the correct general idea, but isn’t accounting for the fact that you want to invert the Y axis (because you want top-to-bottom, and GetPixels gives you bottom-to-top).
I believe this will get the pixels in your desired order:
for (int column = 0; column < TotalColumns; ++column)
{
for (int row = 0; row < TotalRows; ++row)
{
int currentPixelIndex = column + TotalColumns*(TotalRows - row - 1);
Color currentPixel = pixels[currentPixelIndex];
// Do stuff
}
}
In that context it’ll be more efficient to just reverse the loop and save the overhead from the added math. ![]()
Marginally. I felt clarity was more important in this discussion. He may need to know how to perform this coordinate conversion for other reasons.
Thank you for your reply guys, its an immense help for mathless person like me.
i have no problem with texture returing from bottom to top, what i want is make lists of indexes of each column
for example, currently get pixels return like this
0,1,2,3,4,5,6,7,8
in 2d, it will look like this (in my mind)
6,7,8
3,4,5
0,1,2
so i want to get each column in its own array
so first array
6
3
0
second array
7
4
1
and so on.
so which will be the most efficient way and to do that?
@Antistone or
for (int column = 0; column < TextureWidth; ++column)
{
int[] currentColumn = new int[TextureHeight];
for (int row = 0; row < TextureHeight; ++row)
{
int currentPixelIndex = column + TextureWidth*(TextureHeight - row - 1);
currentColumn[i] = currentPixelIndex;
}
//use column here
}
@grizzly ?
I tried but the above approach but its beyond my head, so if you can assist here.
Another problem is, how do i get to upper Cell or Lower Cell in a flattened 2d array.
in simple 2d array, we can simply y-1 = uper, and y+1 lower, but what about flatted array?
Your second array example appears to be reading from the middle row? If you meant 1,4,7 for the middle column then the loop would look like this;
int[,] indices = new int[Width, Height];
for (int x = 0; x < Width; ++x)
{
for (int y = 0; y < Height; ++y)
{
indices[x, y] = x + y * Width;
}
}
// do something with indices[x, y];
To reverse the loop simply replace line 5 with this instead;
for (int y = Height - 1; y >= 0; --y)
The upper bound for 2D is (dimension - 1). For 1D it’s (dimension * dimension - 1).
That’s why I gave you an explicit conversion from row number and column number to array index; that way, you can manipulate the row and column in any way you want and then just plug the result into the same formula.
Thank you guys, really appreciate the help ![]()
Sorry to come back, but (dimension * dimension - 1) is going over my head when i actually start to write it.
For example 2D arrray
[0,0][0,1][0,2][0,3]
[1,0][1,1][1,2][1,3]
if i have [1,2] i can go to cell right above [1,2] by row-1 = [0,2]
Now in Flattened Array
[0][1][2][3][4][5][6][7]
How do i go from [6] to cell directly above which is [2]?
Please advise ![]()
Just add/subtract the number of columns.
Your grid is 4 columns wide. So above/below cell 6 is just 6 +/- 4.
Sorry, ignore that - I’d misinterpreted your question which I understood to be referring to Bounds Checking. If you stick to the original equation I posted you’ll be able to read from any row or column.
int GetIndex(int x, int y, int dimension)
{
return x + y * dimension;
}
So with;
[0,0][0,1][0,2][0,3]
[1,0][1,1][1,2][1,3]
Here the dimension is 4 (columns wide) and x = columns and y = rows. So the cell [1,2] is column = 2 row = 1. Plug that in and we get;
2 + 1 * 4 = index 6
Therefore for the row “above” we get;
2 + 0 * 4 = index 2
I should add that to keep the above answer as clear and concise as possible I’ve written it to match your example, however, in code the rows in your array would be ordered from bottom to top;
[1,0][1,1][1,2][1,3]
[0,0][0,1][0,2][0,3]
And by example;
int GetIndex(int x, int y, int dimension)
{
return x + y * dimension;
}
var value = array[GetIndex(column, row - 1, 4)];
Thank you very much guys for helping someone with terrible math and sometime explanation.
Really appreciate.
Hi Guys, another question,
i was getting above and below neighbor of a cell in flatted array by adding subtracting columns as you advised which is working fine.
however when i want to get left and right column then i was done oneDIndex++ (right column) and oneDIndex-- (left column), but looks like its wrong because if my current cell is the first cell of a row then there is no left and it rather goes to below row
so how do i actually get left cell or right cell?
Thanks
Sorry for the late reply, i wasn’t checking my forum account for a while ![]()
You need to check for the boundaries of the grid when getting neighbors in any direction. If you go ‘up’/‘down’ and there’s no neighbour there then you’ll get an index out of bounds error when you try to read the array, while if you go ‘left’/‘right’ and there’s no neighbour there then you’ll wrap around to the next row like you found.
Taking a 2d index (X, Y co-ordinate) and turning it into a 1d index for storing things in an array can also be reversed and done in the other direction if needed using the % and / operators. You can then use that to check if there even is a neighbour to get. Easier explained with code.
// The size of the 2d grid
int xSize = 10;
int ySize = 15;
// A 2d position in the 2d grid
int xPosition = 9;
int yPosition = 7;
// Turn the 2d position into a 1d index
int flatIndex = xPosition + (yPosition * xSize);
// turn the 1d index back into a 2d position
xPosition = flatIndex % xSize;
yPosition = flatIndex / xSize;
// you can use that to do boundary checking when accessing neighbours
// print the indices of each neighbour, if there's a neighbour
// Is X - 1 (left) inside the map boundaries
if ((flatIndex % xSize) - 1 >= 0)
Debug.Log(flatIndex - 1);
// Is X + 1 (right) inside the map boundaries
if ((flatIndex % xSize) + 1 < xSize)
Debug.Log(flatIndex + 1);
// Is Y - 1 (down) inside the map boundaries
if ((flatIndex / xSize) - 1 >= 0)
Debug.Log(flatIndex - xSize);
// Is Y + 1 (up) inside the map boundaries
if ((flatIndex / xSize) + 1 < ySize)
Debug.Log(flatIndex + xSize);
You’ll notice that it only prints 3 numbers. Because ‘right’ was outside the boundaries of the grid.
Thank you very much, you are Math God
i was doing full conversion earlier but you made it way better and optimize ![]()