在 Python 中生成 3D 希尔伯特空间填充曲线的算法

Posted

技术标签:

【中文标题】在 Python 中生成 3D 希尔伯特空间填充曲线的算法【英文标题】:Algorithm for generating a 3D Hilbert space-filling curve in Python 【发布时间】:2013-01-09 06:24:30 【问题描述】:

我想将 RGB 颜色立方体中的点映射到 Python 中的一维列表,以使颜色列表看起来美观且连续。

我相信使用 3D 希尔伯特空间填充曲线是解决此问题的好方法,但我已经搜索并没有找到非常有用的资源来解决这个问题。特别是 Wikipedia 仅提供生成 2D 曲线的示例代码。

【问题讨论】:

【参考方案1】:

这篇论文似乎有相当的讨论: An inventory of three-dimensional Hilbert space-filling curves.

引自摘要:

希尔伯特的二维空间填充曲线因其 许多应用程序的良好局部性。然而,它不是 明确将这条曲线推广到填充的最佳方法是什么 高维空间。我们认为,使 希尔伯特曲线在二维中唯一,由 10694807 共享 三维结构上不同的空间填充曲线。

【讨论】:

【参考方案2】:

我在尝试用 javascript 做同样的事情时遇到了你的问题。我自己想通了。这是一个递归函数,它将一个立方体分成 8 个部分并旋转每个部分,以便它按顺序遍历希尔伯特曲线。参数代表立方体旋转轴的大小:s、位置:xyz 和 3 个向量。示例调用使用 256^3 的立方体,并假设红色、绿色、蓝色数组的长度为 256^3。

这段代码应该很容易适应 python 或其他过程语言。

改编自这里的图片: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);

【讨论】:

【参考方案3】:

工程实践中经常使用的不是严格意义上的 Hilbert (Peano) 曲线,而是 Morton 代码。

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

更容易计算。

【讨论】:

以上是关于在 Python 中生成 3D 希尔伯特空间填充曲线的算法的主要内容,如果未能解决你的问题,请参考以下文章

使用空间填充曲线的空间和时空索引

在Python中生成颜色范围

在 Python 中从两个 1D 数组(2D 图)创建一个 2D 数组(3D 图)(用于计算希尔伯特谱)

如何在matlab中生成概率3D图

稀疏几何的 3d 希尔伯特曲线

python 在Excel 表格中生成 九九乘法表