记录一个希尔伯特曲线笔记

static int hilbert_order(double lng, double lat, int bits) {

static const double LNG_MIN = -180.0, LNG_MAX = 180.0;

static const double LAT_MIN = -90.0, LAT_MAX = 90.0;

int x = (int)((lng - LNG_MIN) / (LNG_MAX - LNG_MIN) * ((1 << bits) - 1));

int y = (int)((lat - LAT_MIN) / (LAT_MAX - LAT_MIN) * ((1 << bits) - 1));

if (x < 0) x = 0; if (x >= (1 << bits)) x = (1 << bits) - 1;

if (y < 0) y = 0; if (y >= (1 << bits)) y = (1 << bits) - 1;

unsigned int d = 0;

for (int s = bits - 1; s >= 0; s--) {

int rx = (x >> s) & 1;

int ry = (y >> s) & 1;

d += (1 << (2 * s)) * ((3 * rx) ^ ry);

if (ry == 0) {

if (rx == 1) { x = (1 << bits) - 1 - x; y = (1 << bits) - 1 - y; }

int tmp = x; x = y; y = tmp;

}

}

return (int)d;

}

x=0 x=1 x=2 x=3 || x=4 x=5 x=6 x=7

+-----+-----+-----+-----++-----+-----+-----+-----+

y=7: | 21 | 22 | 25 | 26 || 37 | 38 | 41 | 42 |

+-----+-----+-----+-----++-----+-----+-----+-----+

y=6: | 20 | 23 | 24 | 27 || 36 | 39 | 40 | 43 |

+-----+-----+-----+-----++-----+-----+-----+-----+

------------------------++-----------------------

y=5: | 19 | 18 | 29 | 28 || 35 | 34 | 45 | 44 |

+-----+-----+-----+-----++-----+-----+-----+-----+

y=4: | 16 | 17 | 30 | 31 || 32 | 33 | 46 | 47 |

+=====+=====+=====+=====++=====+=====+=====+=====+

y=3: | 15 | 12 | 11 | 10 || 53 | 52 | 51 | 48 |

+-----+-----+-----+-----++-----+-----+-----+-----+

y=2: | 14 | 13 | 8 | 9 || 54 | 55 | 50 | 49 |

+-----+-----+-----+-----++-----+-----+-----+-----+

------------------------++-----------------------

y=1: | 1 | 2 | 7 | 6 || 57 | 56 | 61 | 62 |

+-----+-----+-----+-----++-----+-----+-----+-----+

y=0: | 0 | 3 | 4 | 5 || 58 | 59 | 60 | 63 |

+-----+-----+-----+-----++-----+-----+-----+-----+

输入
bit = 3

x = 5

y = 3

//计算过程

第1轮循环 (s = 2)

  • rx = (x >> 2) & 1 = (5>>2=1) & 1 = 1

  • ry = (y >> 2) & 1 = (3>>2=0) & 1 = 0

  • 计算 (3 * rx) ^ ry = (3*1) ^ 0 = 3 ^ 0 = 3

  • 累加:d += (1 << (2*2)) * 3 = (1<<4) * 3 = 16 * 3 = 48 → 此时 d = 48

  • 判断 if (ry == 0):成立

    • if (rx == 1):成立 → 执行翻转:

      • x = (1<<3)-1 - x = 7 - 5 = 2

      • y = (1<<3)-1 - y = 7 - 3 = 4

    • 交换 xyx = 4, y = 2(原 x=2, y=4 交换后)

  • 此时 (x, y) = (4, 2)

第2轮循环 (s = 1)

  • 当前 x=4 (二进制 100),y=2 (二进制 010)

  • rx = (4 >> 1) & 1 = (2) & 1 = 0

  • ry = (2 >> 1) & 1 = (1) & 1 = 1

  • 计算 (3 * 0) ^ 1 = 0 ^ 1 = 1

  • 累加:d += (1 << (2*1)) * 1 = (1<<2) * 1 = 4 * 1 = 4 → 此时 d = 48 + 4 = 52

  • 判断 if (ry == 0)ry=1,不成立 → 跳过坐标变换

第3轮循环 (s = 0)

  • 当前 x=4 (二进制 100),y=2 (二进制 010)

  • rx = (4 >> 0) & 1 = 0

  • ry = (2 >> 0) & 1 = 0

  • 计算 (3 * 0) ^ 0 = 0

  • 累加:d += (1 << 0) * 0 = 0d 保持 52

  • 判断 if (ry == 0):成立

    • if (rx == 1)rx=0,不翻转

    • 交换 xyx = 2, y = 4(但后续不再使用)

  • 循环结束

输出52

Q 第1轮循环 (s = 2) rx = (x >> 2) & 1 = (5>>2=1) & 1 = 1 ry = (y >> 2) & 1 = (3>>2=0) & 1 = 0 计算 (3 * rx) ^ ry = (3*1) ^ 0 = 3 ^ 0 = 3 累加:d += (1 << (2*2)) * 3 = (1<<4) * 3 = 16 * 3 = 48 → 此时 d = 48 这个48是啥意思 在这个图上

可以把 d 看成四 进制数:d = (高位数字)*16 + (低位数字)

  • 高位数字 3 决定它在哪个 4×4 大块,乘 16 后就是该大块的起始索引。

  • 低位数字(0~15)表示在这个大块内的具体位置。

    对于 (5,3),高位=3 → 基地址 48,低位=4 → 最终 52(因为大块内索引 4 对应点 (5,3))。

所以 48 就是右下大块的起始索引 ,你可以在矩阵中找到右下大块内最小的数字就是 48(在 y=0, x=7 处)

相关推荐
江屿风2 小时前
C++OJ题经验总结(竞赛)1
开发语言·c++·笔记·算法
wangcheng3032 小时前
AI+制造正悄然改变工业生产
笔记
晓梦林3 小时前
homelab2靶场学习笔记
笔记·学习
sheeta19983 小时前
LeetCode 每日一题笔记 日期:2026.05.19 题目:2540. 最小公共值
笔记·leetcode·排序算法
LN花开富贵3 小时前
Ubuntu aarch64 架构安装 NoMachine 远程控制 避坑与实战
linux·运维·笔记·学习·ubuntu·嵌入式
不是山谷.:.4 小时前
前端性能优化全解析:从原理到落地,覆盖全领域与多技术栈
前端·笔记·性能优化·状态模式
dusk_star5 小时前
go语言--笔记--封装、组合(继承)
笔记·golang
不动明王呀5 小时前
almalinux8.10用户添加到root权限笔记
笔记
不是光头 强5 小时前
Java 后端实战进阶:从踩坑到架构的系统化笔记
java·笔记·架构