添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
首发于 软硬兼施

浏览器中实现的Sierpinski地毯

Sierpinski地毯,也称谢尔宾斯基地毯,是一种用正方形构建的典型的分形图,在介绍分形时也经常作为例子。Sierpinski地毯也是可以使用函数递归方式绘制,主要绘制函数代码为:

function drawRect(n,context,x,y,w,h){

if(n==0) return;

context.fillRect(x,y,w,h);

drawRect(n-1,context,(x+(1/3)*w),(y-(2/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(1/3)*w),(y+(4/3)*h),w/3,h/3);

drawRect(n-1,context,(x-(2/3)*w),(y+(1/3)*h),w/3,h/3);

drawRect(n-1,context,(x-(2/3)*w),(y-(2/3)*h),w/3,h/3);

drawRect(n-1,context,(x-(2/3)*w),(y+(4/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(4/3)*w),(y+(1/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(4/3)*w),(y-(2/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(4/3)*w),(y+(4/3)*h),w/3,h/3);

}

其中代码也是JavaScript,函数有6个参数,n为递归函数的递归深度,context为绘制图形使用的html5的canvas上下文,这是一种标准用法。后面四个参数为绘制正方形的左上角顶点坐标x和y,后面是正方形的宽度w和高度h。

使用JavaScript在canvas中绘制正方形使用context的fillRect(x,y,w,h)方法,四个参数x、y、w、h就是这个方法要用到的。在递归使用时,要先绘出中心的一个正方形,然后在其周边用递归调用方法再绘8个正方形,逐次进行下去。为了绘出周边的8个正方形,就要根据中心正方形的坐标计算出周围正方形的顶点坐标,宽度高度都按1/3绘制。

if(n==0) return是用来控制递归深度的,避免造成栈溢出。最初一次调用设定深度值,然后每次递归调用都减去1,直到0时退出。

为了使用上述绘制函数,前面要加上获取canvas及context的代码,为了适应不同的canvas宽度和高度,也设置了几个变量。然后把这些JavaScript代码加入一个网页的html框架中。最终代码为:

<!DOCTYPE html>

<html lang="zh-Hans">

<head>

<meta charset="gb18030" />

<meta http-equiv="refresh" content="9999" />

<title>分形</title>

</head>

<body>

<canvas id="canvas" width="600" height="600"> 你使用的浏览器不支持需要的功能,请升级或更换!</canvas>

<script type="text/javascript">

var canvas = document.getElementById('canvas'),

ctx = canvas.getContext('2d'),

width=canvas.width,

height=canvas.height,

ww=canvas.width/3,

hh=canvas.height/3,

halfwidth=canvas.width/2,

halfheight=canvas.height/2;

window.onload=function() {

ctx.lineWidth=1;

ctx.fillStyle='#66aaaa';

drawRect(5,ctx,halfwidth-ww/2,halfheight-hh/2,ww,hh);

};

function drawRect(n,context,x,y,w,h){

if(n==0) return;

context.fillRect(x,y,w,h);

drawRect(n-1,context,(x+(1/3)*w),(y-(2/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(1/3)*w),(y+(4/3)*h),w/3,h/3);

drawRect(n-1,context,(x-(2/3)*w),(y+(1/3)*h),w/3,h/3);

drawRect(n-1,context,(x-(2/3)*w),(y-(2/3)*h),w/3,h/3);

drawRect(n-1,context,(x-(2/3)*w),(y+(4/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(4/3)*w),(y+(1/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(4/3)*w),(y-(2/3)*h),w/3,h/3);

drawRect(n-1,context,(x+(4/3)*w),(y+(4/3)*h),w/3,h/3);

}

</script>

</body>

</html>

因为绘制是使用fillRect(x,y,w,h)方法,其中需要用到填充正方形空间的颜色,这里使用ctx.fillStyle='#66aaaa'来设置,可以通过更改后面的6个16进制数值来改变颜色。

把上述代码复制到一种不带格式的编辑器中,比如我常使用的notepad++,当然也可以使用vscode等其他程序编辑软件,存为.html文件,比如存到桌面上,然后就可以直接点击这个文件,让其在默认浏览器中运行,然后就能显示出图形。

感兴趣的可以试试效果。

发布于 2020-02-15 21:47

文章被以下专栏收录