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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With