Search code examples
arraysccoordinatescoordinate-transformation

XYZ to a linear value and vice-versa


I have my 3D world x, y, z. I can easily convert given coordinates x, y, z to an integer using my macro XYZ:

const ulong WORLD_SIZE_X = 60;
const ulong WORLD_SIZE_Y = 60;
const ulong WORLD_SIZE_Z = 60;
const ulong WORLD_SIZE = WORLD_SIZE_X * WORLD_SIZE_Y * WORLD_SIZE_Z;
#define XYZ(_x, _y, _z) \
    ((_x) + ((_y)*WORLD_SIZE_X) + ((_z)*WORLD_SIZE_X*WORLD_SIZE_Y))

Hence I can allocate a big "linear" array via calloc(WORLD_SIZE, sizeof(Cube)), and I can access to any cube like this (just an example):

for (int z=0; z<=WORLD_SIZE_Z; ++z) {
    for (int y=0; y<=WORLD_SIZE_Y; ++y) {
        for (int x=0; x<=WORLD_SIZE_X; ++x) {
            printf("blabla\n", myWorld(XYZ(x, y, z));
        }
    }
}

So:

  • I can allocate a "linear" array (= much simpler for me than array of array of array)
  • given x, y and z, I can easily find the element I want

And I cant find the right macro that do the opposite: given a long long pos, find x, y and z.

For a 2D array it's simple, it's x = pos % SIZE_X; and y = (int)(pos / SIZE_X);. But for a 3D world how do you do?


Solution

  • Perhaps it is easier if you rewrite your equation:

    u = (z * WORLD_SIZE_Y + y) * WORLD_SIZE_X + x;
    

    You can get the individual coordinates with:

    x = u % WORLD_SIZE_X;
    y = (u / WORLD_SIZE_X) % WORLD_SIZE_Y;
    z = (u / WORLD_SIZE_X) / WORLD_SIZE_Y;