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

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 处)

相关推荐
Shell运维手记26 分钟前
Linux mdadm 软 RAID + LVM 完整综合笔记
linux·运维·笔记·5g
疯狂打码的少年39 分钟前
【数据库技术】SQL数据查询(SELECT基本语法)
数据库·笔记·sql·oracle
Made in Haven7121 小时前
HTML课程笔记补2
前端·笔记·html
夕除1 小时前
redis--010
笔记·分布式·学习
ouynagda2 小时前
HTTP协议与Socket网络编程笔记
网络·笔记·http
摇滚侠2 小时前
《SpringBoot 3:入门与应用实战》第 10 章 REST 服务请求与调用 Reactor 与 WebFlux 笔记 28
spring boot·笔记·后端
幸运小圣2 小时前
JavaScript 关键字与保留字学习笔记详细讲解,一篇get ✅【JavaScript查缺补漏】
javascript·笔记·学习
十铭忘3 小时前
英语介词怎么理解?
笔记
STQY燊桐启元(深圳)电子科技4 小时前
太阳能追踪设备散热优化,相变陶瓷片解决全日照高温积温故障
经验分享·笔记·pcm
️学习的小王4 小时前
Flask实现云栖笔记|开箱即用网页版本地笔记本
笔记·python·flask