希尔伯特曲线实验室
混淆的效果看不见过程,这一页把它拆开:左边是重排时使用的那条曲线,右边是同一套规则作用在一张测试图上的样子。两边用的是完全相同的代码。
曲线的走向
从绿点出发,按色相由暖到冷一路走满整张网格,红点是终点。
像素被搬去了哪里
同一张测试图,按曲线整体平移一个黄金分割步长后的样子。
加载中…
这一页在演示什么
左侧画的是重排算法真正使用的那条曲线。生成方式是递归的:把矩形切成两三块, 每块再用同样的方法切下去,直到只剩一行或一列时直接填满。 因此它没有随机性——同样的网格尺寸,永远生成同一条曲线。
右侧用的是同一份曲线数据。测试图是一张按位置着色的渐变色块,四角有红、黑、白三个标记点。 当你点“执行混淆”时,每个色块会沿着曲线被搬到 0.618 倍总数之后的位置。 渐变消失、标记点散开,说明局部相邻关系被彻底打乱。
怎么玩
- 先调到 8 × 8。格子少的时候,曲线路径与每个格子的序号都看得清,适合第一次理解。
- 勾选“显示格子序号”。格子足够大时,每个格子里会写出它在曲线上的名次,起点是 0。
- 拖动演示速度。慢速可以看清曲线在拐弯处如何回卷;快速则能一秒看完整体形态。
- 点“执行混淆”。右侧画面立刻被打散,再点一次“还原排布”,一切归位——这就是本站工具的完整逻辑。
- 逐步放大到 48 × 48。观察曲线越密时,画面上的打散效果如何越来越接近均匀噪声。
该观察什么现象
- 没有长距离跳跃。曲线每个相邻名次之间只移动一格,这正是它能保持局部性的原因。
- 色相是连续的。暖色区域在画面上连成一片,说明曲线上的连续区间对应画面上的连通区域。
- 序号在对角线附近发生大跨度。希尔伯特曲线在递归的连接处会出现明显的“翻折”,那是两块子区域之间的过渡。
- 打散后的画面没有明显结构。如果还能看出条带或格纹,说明位移量选得不好——这就是为什么不取总数的二分之一,而取 0.618 倍。
背后的数学
设网格为 w × h,曲线给出的名次表为 path[i],
位移量 s = round((√5 − 1) / 2 × w × h)。
混淆时把名次 i 处的色块写到 (i + s) mod (w×h) 的位置,解混淆反过来。
因为 s 与总数互质的情况居多,连续平移若干次也不会提前回到原位,
这就是右侧演示里画面看起来“毫无规律”的原因。完整的推导见算法原理。
答疑
演示的曲线和实际处理用的是同一条吗?
是同一条。两个页面加载同一个内核文件,曲线生成函数完全共享,不存在“演示版”和“正式版”的差别。
为什么格子序号只在较大网格下显示?
格子太小的时候文字会糊成一团,反而看不清。需要看序号请把网格调到 24 × 24 以下。
动画会拖慢我的设备吗?
演示网格最大 48 × 48,共 2304 个格子,绘制开销很小。在低端设备上如果觉得卡顿,可以把演示速度调快,动画会更快结束。