简体   繁体   中英

Multi-Dimensional Array to Single-Dimensional Index Math

Since we cannot serialize multi-dimensional arrays (in Unity) we are limited to using one dimensional arrays along with math to convert from x,y pairs to an index and back out. Here are the current conversion algorithms:

int Width = 3; // Number of cells along the x axis
int Height = 3; // Number of cells along the y axis

GameObject[] Cells = new GameObject[ Width * Height ]; 

public int CalculateIndex( int x, int y )
{
    return y * Width + x;
}

public void CalculateXY(int i, out x, out y)
{
    x = i % Width;
    y = i / Width;
}

Now, I have the problem where I need to create a 3 dimensional grid which introduces Depth as well as the z axis but I can't figure out how to inject the changes into the methods above... I'm having a mental block.

I found this post that explains some of it:

How to "flatten" or "index" 3D-array in 1D array?

However, my array is not in the HEIGHT, WIDTH, DEPTH (y,x,z) order but rather the WIDTH, HEIGHT, DEPTH (x,y,z) order. Furthermore I need the algorithm to turn it from an index back into x,y,z values.

Thanks, - jeff

Edit: please check the link shared by pijemcolu, good explanation is there.

~~

I'm using JS code so that you / others can directly test it below.

The main functions that you are looking for are:

function CalculateIndex(x, y, z)
{
    return (x * HEIGHT * DEPTH) + (y * DEPTH) + z;
}

function CalculateXYZ(i)
{
  var ret = {};
  ret.x = Math.floor(i / (DEPTH * HEIGHT));
  ret.y = Math.floor(i / DEPTH) % HEIGHT;
  ret.z = i % DEPTH;

  return ret;
}

Note: you won't need to use floor as you are using int datatype in C#.

 $(function(){ $('#process').click(function(){ var WIDTH = +$('#w').val(); var HEIGHT = +$('#h').val(); var DEPTH = +$('#d').val(); var _x = +$('#X').val(); var _y = +$('#Y').val(); var _z = +$('#Z').val(); if(_x >= WIDTH || _y >= HEIGHT || _z >= DEPTH) { $('#output').text('Invalid input'); return; } function CalculateIndex(x, y, z) { return (x * HEIGHT * DEPTH) + (y * DEPTH) + z; } function CalculateXYZ(i) { var ret = {}; ret.x = Math.floor(i / (DEPTH * HEIGHT)); ret.y = Math.floor(i / DEPTH) % HEIGHT; ret.z = i % DEPTH; return ret; } var ind = CalculateIndex(_x, _y, _z); var retXYZ = CalculateXYZ(ind); $('#output').html('Calculated index is: ' + ind + '<br/>' + 'Calulated XYZ are: ' + JSON.stringify(retXYZ)); }); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>Width: <input id='w' type='number' value='4' min=0></p> <p>Height: <input id='h' type='number' value='3' min=0></p> <p>Depth: <input id='d' type='number' value='2' min=0></p> <hr> <p>x: <input id='X' type='number' value='0' min=0></p> <p>y: <input id='Y' type='number' value='0' min=0></p> <p>z: <input id='Z' type='number' value='0' min=0></p> <p><button id='process'>Process XY Z</button></p> <div id='output'></div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM