将勒贝格曲线转换为希尔伯特曲线

时间:2017-01-12 20:06:39

标签: c math hilbert-curve

我将空间数据映射到一维间隔。首先,我使用空间填充勒贝格曲线(或Z曲线)来连接我的点。这有效,如果我使用gnuplot,我会得到以下情节:

enter image description here

然后我想将勒贝格曲线转换为希尔伯特曲线。但它不起作用。这是输出:

enter image description here

所以它似乎在开始时起作用。但过了一会儿奇怪的事情发生了,我不知道为什么。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <stdint.h>

#define DIM 2

// direction of hilbert curve
const unsigned char DirTable[4][4] = 
{{1,2,0,0},{0,1,3,1},{2,0,2,3},{3,3,1,2}};

// Map z-order to hilbert curve
const unsigned char HilbertTable[4][4] =
{{0,3,1,2},{0,1,3,2},{2,3,1,0},{2,1,3,0}};

unsigned int Lebesgue2Hilbert(unsigned int lebesgue){
    unsigned int hilbert = 1;
    int level = 0;
    int dir = 0;
    for(unsigned int tmp=lebesgue; tmp>1; tmp>>=DIM, level++);
    for(; level>0; level--){
        int cell = (lebesgue >> ((level-1)*DIM)) & ((1<<DIM)-1);
        hilbert = (hilbert<<DIM) + HilbertTable[dir][cell];
        dir = DirTable[dir][cell];
    }
    return hilbert;
}

unsigned int Part1By1(unsigned int x)
{
  x &= 0x0000ffff;
  x = (x ^ (x <<  8)) & 0x00ff00ff;
  x = (x ^ (x <<  4)) & 0x0f0f0f0f;
  x = (x ^ (x <<  2)) & 0x33333333;
  x = (x ^ (x <<  1)) & 0x55555555;
  return x;
}

unsigned int EncodeMorton2(unsigned int x, unsigned int y)
{
  return (Part1By1(y) << 1) + Part1By1(x);
}

struct sortKey{
    int idx;
    int key;
};

int compare (const void * a, const void * b)
{
    return ( (*(struct sortKey*)b).key - (*(struct sortKey*)a).key );
}

int uniform_distribution(int rangeLow, int rangeHigh) {
    double myRand = rand()/(1.0 + RAND_MAX); 
    int range = rangeHigh - rangeLow + 1;
    int myRand_scaled = (myRand * range) + rangeLow;
    return myRand_scaled;
}

int main (int argc, char **argv){
    srand(time(NULL));

    int n = 20;
    int N = n*n;

    // Uniform distribution    
    unsigned int pospar[DIM*N];
    int k = 0;
    for(unsigned int i=0; i<n; i++){
        for(unsigned int j=0; j<n; j++){
            pospar[DIM*k] = i;
            pospar[DIM*k+1] = j;
            k++;
        }
    }

    // Lebesgue curve
    unsigned int lkey[N];
    for(int i=0; i<N; i++){
        lkey[i] = EncodeMorton2(pospar[i*DIM+0],pospar[i*DIM+1]);
    //    printf("Lkey: %d\n", lkey[i]);
    }

    // Hilbert curve 
    unsigned int hkey[N];
    for(int i=0; i<N; i++){
        hkey[i] = Lebesgue2Hilbert(lkey[i]);
    }

    struct sortKey sk[N];
    for(int i=0;i<N; i++){
        sk[i].idx = i;
        sk[i].key = hkey[i]; // "lkey[i]" or "hkey[i]"
    }

    qsort (sk, N, sizeof(struct sortKey), compare);

    for (int i=0; i<N; i++){
        printf ("%d %d\n", pospar[DIM*sk[i].idx], pospar[DIM*sk[i].idx+1]);
    }

    return 0;
}

有人看到我错过了吗?

0 个答案:

没有答案