我想将RGB颜色立方体中的点映射到Python中的一维列表,以使颜色列表看起来漂亮且连续。
我相信使用 3D 希尔伯特空间填充曲线将是一个很好的方法,但我已经搜索过,没有找到解决这个问题的非常有用的资源。特别是维基百科仅提供生成2D曲线的示例代码。
这篇论文似乎有相当多的讨论:三维希尔伯特空间填充曲线的清单。
引用摘要:
希尔伯特的二维空间填充曲线因其 适合许多应用的良好局部性。但是,事实并非如此 明确将此曲线推广到填充的最佳方法是什么 高维空间。我们认为,使 希尔伯特曲线在二维上是唯一的,由10694807共享 三维结构不同的空间填充曲线。
我在尝试在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);
工程实践中经常使用的不是严格的希尔伯特(皮亚诺)曲线 - 它是莫顿代码。
https://en.wikipedia.org/wiki/Z-order_curve
更容易计算。