Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Z-order-curve coordinates

Tags:

c++

How could i access data which is being stored using Z-order with O(1) time complexity in array? I need fast access to each of element by their coordinates. I there any faster way to access this data than using while to shift bits?

One way would be using lookup tables (i have static size of data)

EDIT:

One idea i had right now is to store leaves in sequence using y*SIZE+x

EDIT 2.:

I am storying bits in quad tree in std::bitset. I am trying to do checks if some data is available. in matrices of size 128*128. So i can skip bruteforce matrix search for empty data.

like image 848
BlackCat Avatar asked Aug 28 '12 10:08

BlackCat


People also ask

What is Z-order in computing?

Z-order is an ordering of overlapping two-dimensional objects, such as windows in a stacking window manager, shapes in a vector graphics editor, or objects in a 3D application. One of the features of a typical GUI is that windows may overlap, so that one window hides part or all of another.

What is Morton ordering?

The Morton ordering (or z-ordering) of a matrix lays out the elements along a recursive z-shaped curve, as shown in the figure of four iterations of the Z-order curve (from Wikipedia). You can compute the Morton index z from the x- and y-indices ( i and j respectively) by interleaving their bits.

What are space filling curves?

Definition. A space-filling curve (SFC) is a way of mapping the multi-dimensional space into the one-dimensional space. It acts like a thread that passes through every cell element (or pixel) in the multi-dimensional space so that every cell is visited exactly once.


1 Answers

You can calculate the z order curve value with the following code:

uint32_t calcZOrder(uint16_t xPos, uint16_t yPos)
{
    static const uint32_t MASKS[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF};
    static const uint32_t SHIFTS[] = {1, 2, 4, 8};

    uint32_t x = xPos;  // Interleave lower 16 bits of x and y, so the bits of x
    uint32_t y = yPos;  // are in the even positions and bits from y in the odd;

    x = (x | (x << SHIFTS[3])) & MASKS[3];
    x = (x | (x << SHIFTS[2])) & MASKS[2];
    x = (x | (x << SHIFTS[1])) & MASKS[1];
    x = (x | (x << SHIFTS[0])) & MASKS[0];

    y = (y | (y << SHIFTS[3])) & MASKS[3];
    y = (y | (y << SHIFTS[2])) & MASKS[2];
    y = (y | (y << SHIFTS[1])) & MASKS[1];
    y = (y | (y << SHIFTS[0])) & MASKS[0];

    const uint32_t result = x | (y << 1);
    return result;
}

It was taken from here Bit Twiddling Hacks

From you 128x128 array (or any other size) you can calculate easily the z order curve value from any position. For example:

xPos = 2, yPos = 3 -> z order curve value = 7

The max array size for the example code is 65536*65536. Just use a power of 2 for ease, in that case the maximum wasted space is approx. 3/4

like image 175
aggsol Avatar answered Oct 04 '22 00:10

aggsol