モートン オーダー (Morton-Order, Z-order)
モートンキーの算出方法
モートンキーは、XYの位置情報を1ビットずつを交互に並べたものである
空間分割レベル2であり、空間数が16個ある場合の例が下記である
2進数表記
10進数表記
XY方向の位置情報を1ビットずつ交互に並べることによって、16個の空間を
Zを描くように辿ることができる
三次元空間の場合は、Z方向が加わるため、
ZYX ZYX ZYXとビットを並べることでモートンキーを算出することができる
モートンキーの計算をコードに起こしてみる
二次元用
7行目から10行目では、X方向の位置情報をモートンキー算出用にビットセパレートする12行目から15行目では、Y方向の位置情報をモートンキー算出用にビットセパレートする
ビットセパレートしたものを、17行目で結合することで、
XYの位置情報を1ビットずつ交互に並べている
// MortonKey from x, y unsigned int GetMortonKey2D(unsigned int x, unsigned int y){ unsigned int bitx, bity; bitx = x; bity = y; // 0x00ff00ff : 0000 0000 1111 1111 0000 0000 1111 1111 // 0x0f0f0f0f : 0000 1111 0000 1111 0000 1111 0000 1111 // 0x33333333 : 0011 0011 0011 0011 0011 0011 0011 0011 // 0x55555555 : 0101 0101 0101 0101 0101 0101 0101 0101 bitx = (bitx|(bitx<<8)) & 0x00ff00ff; bitx = (bitx|(bitx<<4)) & 0x0f0f0f0f; bitx = (bitx|(bitx<<2)) & 0x33333333; bitx = (bitx|(bitx<<1)) & 0x55555555; bity = (bity|(bity<<8)) & 0x00ff00ff; bity = (bity|(bity<<4)) & 0x0f0f0f0f; bity = (bity|(bity<<2)) & 0x33333333; bity = (bity|(bity<<1)) & 0x55555555; return bitx | bity<<1; }
三次元用
// MortonKey from x, y, z unsigned int GetMortonKey3D(unsigned int x, unsigned int y, unsigned int z){ unsigned int bitx, bity, bitz; bitx = x; bity = y; bitz = z; // 0x030000ff : 0011 0000 0000 0000 0000 1111 1111 // 0x0300f00f : 0011 0000 0000 1111 0000 0000 1111 // 0x030c30c3 : 0011 0000 1100 0011 0000 1100 0011 // 0x09249249 : 1001 0010 0100 1001 0010 0100 1001 bitx = (bitx|(bitx<<16)) & 0x030000ff; bitx = (bitx|(bitx<< 8)) & 0x0300f00f; bitx = (bitx|(bitx<< 4)) & 0x030c30c3; bitx = (bitx|(bitx<< 2)) & 0x09249249; bity = (bity|(bity<<16)) & 0x030000ff; bity = (bity|(bity<< 8)) & 0x0300f00f; bity = (bity|(bity<< 4)) & 0x030c30c3; bity = (bity|(bity<< 2)) & 0x09249249; bitz = (bitz|(bitz<<16)) & 0x030000ff; bitz = (bitz|(bitz<< 8)) & 0x0300f00f; bitz = (bitz|(bitz<< 4)) & 0x030c30c3; bitz = (bitz|(bitz<< 2)) & 0x09249249; return bitx | bity<<1 | bitz<<2; }
ヒルベルト曲線 ( Hilbert Curve )
ヒルベルトキー算出方法二次元用
// HilbertKey from x, y, n unsigned int GetHilbertKey2D(unsigned int x, unsigned int y, unsigned int n){ int i, ix, iy; unsigned int s, temp; s = 0; for( i=n-1; i>=0; i-- ){ ix = (x >> i) &1; iy = (y >> i) &1; if( iy == 0 ){ temp = x; x = y^(-ix); y = temp^(-ix); } s = 4*s + 2*ix + (ix^iy); } return s; }
0 件のコメント:
コメントを投稿