希尔伯特曲线 java_分形的乐趣之_Hilbert曲线

作者:路缘

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

f3f771c922fa9d412dc6556f127c4584.png

Hibert曲线生成过程

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

b8499010da4e0b6425e183eba864e89b.png

基本图

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

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

86c770057e306bb059e08a7ca33bd43f.png

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

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

点所在图类型

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

dot1

0

1

dot1

1

2

dot1

2

3

dot1

3

0

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

图像旋转

图像旋转是指把定义的图像绕某一点以逆时针或顺时针方向旋转一定的角度,通常是指绕图像的中心以逆时针方向旋转。

假设图像的左上角为(left, top),右下角为(right, bottom),则图像上任意点(x0, y0)绕其中心(xcenter, ycenter)逆时针旋转angle角度后,新的坐标位置(x′, y′)的计算公式为:

xcenter = (right - left + 1) / 2 + left;

ycenter = (bottom - top + 1) / 2 + top;

x′ =  (x0 - xcenter) cosθ - (y0 - ycenter) sinθ + xcenter;

y′ =  (x0 - xcenter) sinθ + (y0 - ycenter) cosθ + ycenter;

与图像的镜像变换相类似,也采用按行逐点变换的方式实现图像的旋转。

现在一切都准备就绪,我们来实现相关的算法如下:

34031c708bfe702fe82d01ff5c6593aa.png

0be121fa5b8988fbabbbc526af3b0fc0.gif/**//**********************************************************************************************

587e34b10dcf5efbc0859b53470a2db3.png功能:实现绘制Hilbert曲线

587e34b10dcf5efbc0859b53470a2db3.png参数:

587e34b10dcf5efbc0859b53470a2db3.png    pDC:设备上下文

587e34b10dcf5efbc0859b53470a2db3.png    n:维都

587e34b10dcf5efbc0859b53470a2db3.png    len:边长

587e34b10dcf5efbc0859b53470a2db3.png    x:中心横坐标

587e34b10dcf5efbc0859b53470a2db3.png    y:中心纵坐标

587e34b10dcf5efbc0859b53470a2db3.png    iType:绘画类型,开口:0-南,1-西,2-北,3-东

587e34b10dcf5efbc0859b53470a2db3.png    unit_length:最小单元长度

4fd96b3cf02f4c7b5c8964ac8167f7af.png/**********************************************************************************************/f0cd6c7f9e7ae96feae062cb48f670f0.pngvoidCGraphicAppView::DrawHilbert(CDC*pDC,intn

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值