Algorithm for generating a 3D Hilbert space-fillin

2020-02-05 02:39发布

I'd like to map points in a RGB color cube to a one-dimensional list in Python, in a way that makes the list of colors look nice and continuous.

I believe using a 3D Hilbert space-filling curve would be a good way to do this, but I've searched and haven't found very helpful resources for this problem. Wikipedia in particular only provides example code for generating 2D curves.

3条回答
欢心
2楼-- · 2020-02-05 03:07

I came across your question while trying to do the same thing in javascript. I figured it out on my own. Here is a recursive function that breaks a cube in 8 parts and rotates each part so that it traverses a hilbert curve in order. The arguments represent the size:s, location:xyz, and 3 vectors for the rotated axes of the cube. The example call uses a 256^3 cube and assumes red,green,blue arrays have length 256^3.

It should be easy to adapt this code to python or other procedural languages.

Adapted from pictures here: http://www.math.uwaterloo.ca/~wgilbert/Research/HilbertCurve/HilbertCurve.html

    function hilbertC(s, x, y, z, dx, dy, dz, dx2, dy2, dz2, dx3, dy3, dz3)
    {
        if(s==1)
        {
            red[m] = x;
            green[m] = y;
            blue[m] = z;
            m++;
        }
        else
        {
            s/=2;
            if(dx<0) x-=s*dx;
            if(dy<0) y-=s*dy;
            if(dz<0) z-=s*dz;
            if(dx2<0) x-=s*dx2;
            if(dy2<0) y-=s*dy2;
            if(dz2<0) z-=s*dz2;
            if(dx3<0) x-=s*dx3;
            if(dy3<0) y-=s*dy3;
            if(dz3<0) z-=s*dz3;
            hilbertC(s, x, y, z, dx2, dy2, dz2, dx3, dy3, dz3, dx, dy, dz);
            hilbertC(s, x+s*dx, y+s*dy, z+s*dz, dx3, dy3, dz3, dx, dy, dz, dx2, dy2, dz2);
            hilbertC(s, x+s*dx+s*dx2, y+s*dy+s*dy2, z+s*dz+s*dz2, dx3, dy3, dz3, dx, dy, dz, dx2, dy2, dz2);
            hilbertC(s, x+s*dx2, y+s*dy2, z+s*dz2, -dx, -dy, -dz, -dx2, -dy2, -dz2, dx3, dy3, dz3);
            hilbertC(s, x+s*dx2+s*dx3, y+s*dy2+s*dy3, z+s*dz2+s*dz3, -dx, -dy, -dz, -dx2, -dy2, -dz2, dx3, dy3, dz3);
            hilbertC(s, x+s*dx+s*dx2+s*dx3, y+s*dy+s*dy2+s*dy3, z+s*dz+s*dz2+s*dz3, -dx3, -dy3, -dz3, dx, dy, dz, -dx2, -dy2, -dz2);
            hilbertC(s, x+s*dx+s*dx3, y+s*dy+s*dy3, z+s*dz+s*dz3, -dx3, -dy3, -dz3, dx, dy, dz, -dx2, -dy2, -dz2);
            hilbertC(s, x+s*dx3, y+s*dy3, z+s*dz3, dx2, dy2, dz2, -dx3, -dy3, -dz3, -dx, -dy, -dz);
        }
    }
    m=0;
    hilbertC(256,0,0,0,1,0,0,0,1,0,0,0,1);
查看更多
▲ chillily
3楼-- · 2020-02-05 03:11

What's frequently used in engineering practice is not strictly Hilbert (Peano) curves - it's Morton code.

https://en.wikipedia.org/wiki/Z-order_curve

Much easier to compute.

查看更多
姐就是有狂的资本
4楼-- · 2020-02-05 03:27

This paper seems to have quite a discussion: An inventory of three-dimensional Hilbert space-filling curves.

Quoting from the abstract:

Hilbert's two-dimensional space-filling curve is appreciated for its good locality properties for many applications. However, it is not clear what is the best way to generalize this curve to filling higher-dimensional spaces. We argue that the properties that make Hilbert's curve unique in two dimensions, are shared by 10694807 structurally different space-filling curves in three dimensions.

查看更多
登录 后发表回答