zoukankan      html  css  js  c++  java
  • Hilbert曲线简单介绍及生成算法

    Hilbert曲线

    Hilbert曲线是一种填充曲线,相似的填充曲线还包含Z曲线。格雷码等其它方法。Hilbert曲线根据自身空间填充曲线的特性,能够线性地贯穿二维或者更高维度每一个离散单元。而且只穿过一次,并对每一个离散单元进行线性排序和编码。该编码作为该单元的唯一标识。

    空间填充曲线能够将高维空间中没有良好顺序的数据映射到一维空间,经过这样的编码方式,空间上相邻的对象会邻近存储在一块,能够降低IO的时间,提高内存中数据处理效率。

    Hilbert曲线例如以下图所看到的:


    Hilbert作用很大。除了上面讲到的作为一种基于网格的空间索引外,还能够用作图像数据的混淆或者加密。

    Hilbert曲线生成的关键是怎样计算每一个离散单元所相应的编码以及根据编码获得离散单元所处的位置。代码例如以下:

    void rot(int n, int *x, int *y, int rx, int ry);
    
    //XY坐标到Hilbert代码转换
    int xy2d (int n, int x, int y)
    {
        int rx, ry, s, d=0;
        for (s=n/2; s>0; s/=2)
        {
            rx = (x & s) > 0;
            ry = (y & s) > 0;
            d += s * s * ((3 * rx) ^ ry);
            rot(s, &x, &y, rx, ry);
        }
        return d;
    }
    
    //Hilbert代码到XY坐标
    void d2xy(int n, int d, int *x, int *y)
    {
        int rx, ry, s, t=d;
        *x = *y = 0;
        for (s=1; s<n; s*=2)
        {
            rx = 1 & (t/2);
            ry = 1 & (t ^ rx);
            rot(s, x, y, rx, ry);
            *x += s * rx;
            *y += s * ry;
            t /= 4;
        }
    }
    
    void rot(int n, int *x, int *y, int rx, int ry)
    {
        if (ry == 0)
        {
            if (rx == 1)
            {
                *x = n-1 - *x;
                *y = n-1 - *y;
            }
    
            //Swap x and y
            int t  = *x;
            *x = *y;
            *y = t;
        }
    }

    代码是维基百科上,结果可靠。上面的代码须要注意的是,变量n是网格在X方向或者Y方向上单元的个数,n必须是2的次方。假设原始的图像宽高数并非2的次方,那么就须要求出最接近2的某个次方的数。

    參考文献:

    地理信息系统算法基础

    https://en.wikipedia.org/wiki/Hilbert_curve- Applications_and_mapping_algorithms

  • 相关阅读:
    西门子1200/1500 PLC FC/FB块的区别
    Monaco Editor --Web编辑器 自定义主题、代码提示等
    C# 强制GC垃圾回收
    C# 注册表操作类(查询、修改、删除)
    WinForm重绘Combobox控件无边框样式
    Http-server搭建本地服务
    C# 压缩解压文件夹
    递归获取当前节点和所有父节点
    递归获取当前父节点下的所有子集
    轻量级的通信引擎 StriveEngine
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/7089977.html
Copyright © 2011-2022 走看看