Hilbert曲线代码和思路

void hilbertCurve()
{
	int g[MAX][MAX];
	int rank = N; 
	int i, j, k; 
	int pow2, pow4; 

	memset(g, -1, sizeof g); 

	g[1][0] = 1; g[1][1] = 2;
	g[0][0] = 0; g[0][1] = 3;

	for(i=2; i<=rank; i++)
	{
		pow2 = (int)pow(2.0, i-1); 
		pow4 = (int)pow(4.0, i-1); 
		for(j=0;j<pow2;j++)
			for(k=0;k<pow2;k++)
			{
				g[j+pow2][k] =  g[j][k]+pow4; //第1象限对应的网格
				g[j+pow2][k+pow2] = g[j][k]+2*pow4; //第2象限对应的网格
				g[pow2-1-k][pow2*2-1-j] = g[j][k]+3*pow4;//第3象限对应的网格
	
		//		printf("mid--------------\n"); 
		//		test(g); 
			}

		for(j=0;j<pow2;j++) //第0象限对应的网格
			for(k=0;k<=j;k++)
			{
				int temp = g[j][k];
				g[j][k] = g[k][j];   //按斜对角线翻转
				g[k][j] = temp; 
			}
	}

	for(j=0;j<pow2*2;j++) //打印曲线表
	{
		for(k=0;k<pow2*2;k++)
		{
			printf("%d\t", g[j][k]); 
		}
		printf("\n"); 
	}
}


 

 

代码如上:

德国数学家David Hilbert发现了一种曲线,首先把一个正方形等分成四个小正方形,依次从西南角的正方形中心出发往北到西北正方形中心,再往东到东北角的正方形中心,再往南到东南角正方形中心,这是一次迭代,如果对四个小正方形继续上述过程,往下划分,反复进行,最终就得到一条可以填满整个正方形的曲线,这就是Hibert曲线,其大致过程如下图所示

 

                                Hibert曲线生成过程

 

下面我们来看如何写程序生成这样的曲线,其实不管迭代多少次,都是由如下的图形

            基本图 

构成,唯一所不同的是开口方向不一样。开口方向不一样就涉及到图像旋转,图像旋转的基本知识接下来会介绍。目前我们最关心的是这样生成的曲线过程右什么规律,从上述描述生成的过程就已经看出了规律,当然人肯定一眼就看出来了,但计算机如何知道呢?这就是生成Hibert曲线算法的关键了:

为了便于找出规律,我们来看下面一副图

 

上图中应该是把所有开口方向(共四种)都涵盖了。我们约定四种类型:

开口往南-0,开口往西-1,开口往北-2,开口往东-3。我们结合基本图,就有这样的规律,画表如下:

点所在图类型

以该点为中心产生的图类型

dot1

0

1

dot1

1

2

dot1

2

3

dot1

3

0

 

其他的点类似也有类似的规律,这个规律才是我们编码的基础。是下次递归调用画图函数传参数的前提。下面我们来看一下画图中涉及到的图像旋转的相关数学知识。

 

思路参考: http://www.cnblogs.com/xuyuan77/archive/2008/10/13/1310269.html
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值