赵工的个人空间


网络课堂部分转网页计算部分转编程演练

 制作有趣的网页

首页 > 网络课堂 > 制作有趣的网页 > canvas中绘制Sierpinski地毯
canvas中绘制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" />
  <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文件,没有外部引用文件因此可以存放在任何位置,比如存到桌面上,然后就可以直接打开这个文件,让其在默认浏览器中运行,就能显示出图形。
Copyright@dwenzhao.cn All Rights Reserved   备案号:粤ICP备15026949号
联系邮箱:dwenzhao@163.com  QQ:1608288659