在“JavaScript图形实例:SierPinski三角形” 和“JavaScript图形实例:Levy曲线及其变形”等文章中我们介绍了通过递归生成分形图形的方法。我们可以将绘制的分形图形每隔一定的时间间隔后,增加递归深度重新绘制一次,这样就可以得到分形图形的动态生成效果。

1.SierPinski垫片

递归深度depth从1开始,将递归绘制的SierPinski垫片每隔1秒后增加递归深度(depth++),重新绘制一遍,得到SierPinski垫片的动态生成动画效果。

编写如下的HTML代码。

<!DOCTYPE>

<html>

<head>

<title>SierPinski三角形</title>

</head>

<body>

<canvas id="myCanvas" width="600" height="600" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var depth=0;

function sierpinski(x1,y1,x2,y2,x3,y3,n)

{

if (n<=0)  return;

var x4 = (x1 + x2) / 2;

var y4 = (y1 + y2) / 2;

var x5 = (x2 + x3) / 2;

var y5 = (y2 + y3) / 2;

var x6 = (x1 + x3) / 2;

var y6 = (y1 + y3) / 2;

ctx.beginPath();

ctx.moveTo(x4,y4);

ctx.lineTo(x5,y5);

ctx.lineTo(x6,y6);

ctx.closePath();

ctx.fill();

sierpinski(x1,y1,x4,y4,x6,y6,n-1);

sierpinski(x6,y6,x5,y5,x3,y3,n-1);

sierpinski(x4,y4,x2,y2,x5,y5,n-1);

}

function go()

{

ctx.beginPath();

ctx.moveTo(300, 500-500*Math.sqrt(3)/2);

ctx.lineTo(50,500);

ctx.lineTo(550,500);

ctx.closePath();

ctx.fillStyle="#00ffff";

ctx.fill();

ctx.fillStyle = "white";

sierpinski(300, 500-500*Math.sqrt(3)/2, 50, 500, 550, 500,depth);

depth++;

if (depth>6)

{

ctx.clearRect(0,0,canvas.width,canvas.height);

depth=0;

}

}

window.setInterval('go()', 1000);

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到SierPinski垫片的动态生成动画,如图1所示。

图1  SierPinski垫片的动态生成

2.SierPinski地毯

递归深度depth从1开始,将递归绘制的SierPinski地毯每隔1秒后增加递归深度(depth++),重新绘制一遍,得到SierPinski地毯的动态生成动画效果。

编写如下的HTML代码。

<!DOCTYPE>

<html>

<head>

<title>SierPinski地毯</title>

</head>

<body>

<canvas id="myCanvas" width="550" height="550" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var depth=0;

function sierpinski(x,y,L,n)

{

if (n<=0)  return;

ctx.fillRect(x+L/3,y+L/3,L/3,L/3);

sierpinski(x,y,L/3,n-1);

sierpinski(x+L/3,y,L/3,n-1);

sierpinski(x+2*L/3,y,L/3,n-1);

sierpinski(x,y+L/3,L/3,n-1);

sierpinski(x+2*L/3,y+L/3,L/3,n-1);

sierpinski(x,y+2*L/3,L/3,n-1);

sierpinski(x+L/3,y+2*L/3,L/3,n-1);

sierpinski(x+2*L/3,y+2*L/3,L/3,n-1);

}

function go()

{

ctx.fillStyle="#00FFFF";

ctx.fillRect(50,50,450,450);

ctx.fillStyle = "white";

sierpinski(50,50,450,depth);

depth++;

if (depth>6)

{

ctx.clearRect(0,0,canvas.width,canvas.height);

depth=0;

}

}

window.setInterval('go()', 1000);

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到SierPinski地毯的动态生成动画,如图2所示。

图2  SierPinski地毯的动态生成

3.维切克分形图

将SierPinski地毯的生成过程调整为:

(1)取一个实心的正方形;

(2)将正方形的每边三等分,并连接相应的等分点,从而将原正方形等分为面积相等的9个小正方形;

(3)去掉上下两行中间的小正方形、中间一行左右两边的小正方形,共4个小正方形;

(4)对其余的5个小正方形重复这一过程。

编写HTML文件内容如下。

<!DOCTYPE>

<html>

<head>

<title>维切克分形图</title>

</head>

<body>

<canvas id="myCanvas" width="550" height="550" style="border:3px double #996633;"></canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var depth=0;

function sierpinski(x,y,L,n)

{

if (n<=0)  return;

ctx.fillRect(x+L/3,y,L/3,L/3);

ctx.fillRect(x,y+L/3,L/3,L/3);

ctx.fillRect(x+2*L/3,y+L/3,L/3,L/3);

ctx.fillRect(x+L/3,y+2*L/3,L/3,L/3);

sierpinski(x,y,L/3,n-1);

sierpinski(x+2*L/3,y,L/3,n-1);

sierpinski(x+L/3,y+L/3,L/3,n-1);

sierpinski(x,y+2*L/3,L/3,n-1);

sierpinski(x+2*L/3,y+2*L/3,L/3,n-1);

}

function go()

{

ctx.fillStyle="#00FFFF";

ctx.fillRect(50,50,450,450);

ctx.fillStyle = "white";

sierpinski(50,50,450,depth);

depth++;

if (depth>6)

{

ctx.clearRect(0,0,canvas.width,canvas.height);

depth=0;

}

}

window.setInterval('go()', 1000);

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到维切克分形图的动态生成动画,如图3所示。

图3 维切克分形图的动态生成

4.C曲线

将C曲线的生成过程进行动画展示,编写如下的HTML代码。

<!DOCTYPE>

<html>

<head>

<title>C曲线</title>

</head>

<body>

<canvas id="myCanvas" width="400" height="400" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var depth=0;

function fractal_c(n,p1,p2)

{

if (n>0)

{

var x3=(p1.x+p1.y+p2.x-p2.y)/2;

var y3=(p2.x+p2.y+p1.y-p1.x)/2;

fractal_c(n-1,p1,{x:x3,y:y3});

fractal_c(n-1,{x:x3,y:y3},p2);

}

if (n==0)

{

ctx.strokeStyle = "red";

ctx.beginPath();

ctx.moveTo(p1.x,p1.y);

ctx.lineTo(p2.x,p2.y);

ctx.closePath();

ctx.stroke();

}

}

function go()

{

ctx.clearRect(0,0,canvas.width,canvas.height);

ctx.lineWidth = 2;

fractal_c(depth,{x:250,y:100},{x:250,y:300});

depth++;

if (depth>12)

{

depth=0;

}

}

window.setInterval('go()', 1000);

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到C曲线的动态生成动画,如图4所示。

图4  C曲线的动态生成

5.龙形线

将龙形线的生成过程进行动画展示,编写如下的HTML代码。

<!DOCTYPE>

<html>

<head>

<title>龙形线</title>

</head>

<body>

<canvas id="myCanvas" width="550" height="400" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var depth=0;

function fractal_c(n,p1,p2,left)

{

if (n>0)

{

if (left)

{

var x3=(p1.x+p1.y+p2.x-p2.y)/2;

var y3=(p2.x+p2.y+p1.y-p1.x)/2;

}

else

{

var x3=(p1.x+p2.y+p2.x-p1.y)/2;

var y3=(p1.x+p2.y+p1.y-p2.x)/2;

}

fractal_c(n-1,p1,{x:x3,y:y3},true);

fractal_c(n-1,{x:x3,y:y3},p2,false);

}

if (n==0)

{

ctx.strokeStyle = "red";

ctx.beginPath();

ctx.moveTo(p1.x,p1.y);

ctx.lineTo(p2.x,p2.y);

ctx.closePath();

ctx.stroke();

}

}

function go()

{

ctx.clearRect(0,0,canvas.width,canvas.height);

ctx.lineWidth = 2;

fractal_c(depth,{x:150,y:150},{x:450,y:150},true);

depth++;

if (depth>12)

{

depth=0;

}

}

window.setInterval('go()', 1000);

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到龙形线的动态生成动画,如图5所示。

图5  龙形线的动态生成

6.Koch曲线

将Koch曲线的生成过程进行动画展示,编写如下的HTML代码。

<!DOCTYPE>

<html>

<head>

<title>koch曲线</title>

</head>

<body>

<canvas id="myCanvas" width="600" height="400" style="border:3px double #996633;">

</canvas>

<script type="text/javascript">

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

var maxdepth =0;

var curdepth = 0;

function Koch(p1,p2,angle)

{

curdepth++;

if (curdepth<=maxdepth)

{

var x1=(2*p1.x+p2.x)/3;

var y1=(2*p1.y+p2.y)/3;

var x3=(2*p2.x+p1.x)/3;

var y3=(2*p2.y+p1.y)/3;

var x2=(x3-x1)*Math.cos(angle)-(y3-y1)*Math.sin(angle)+x1;

var y2=(x3-x1)*Math.sin(angle)+(y3-y1)*Math.cos(angle)+y1;

Koch(p1,{x:x1,y:y1},Math.PI/3);

Koch({x:x1,y:y1},{x:x2,y:y2},Math.PI/3);

Koch({x:x2,y:y2},{x:x3,y:y3},Math.PI/3);

Koch({x:x3,y:y3},p2,Math.PI/3);

}

if (curdepth>maxdepth)

draw([p1,{x:x1,y:y1},{x:x2,y:y2},{x:x3,y:y3},p2]);

curdepth--;

}

function draw(points)

{

ctx.strokeStyle = "red";

ctx.beginPath()

ctx.moveTo(points[0].x,points[0].y)

for(i=1;i<points.length;i++)

{

ctx.lineTo(points[i].x,points[i].y);

}

ctx.closePath()

ctx.stroke()

}

function go()

{

ctx.clearRect(0,0,canvas.width,canvas.height);

ctx.lineWidth = 2;

Koch({x:50,y:150},{x:550,y:150},Math.PI/3);

maxdepth++;

curdepth=0;

if (maxdepth>6)

{

maxdepth=0;

}

}

window.setInterval('go()', 1000);

</script>

</body>

</html>

在浏览器中打开包含这段HTML代码的html文件,可以在浏览器窗口中看到koch曲线的动态生成动画,如图6所示。

图6  Koch曲线的动态生成

JavaScript动画实例:递归分形图动态展示的更多相关文章

  1. JavaScript动画实例:李萨如曲线

    在“JavaScript图形实例:阿基米德螺线”和“JavaScript图形实例:曲线方程”中,我们学习了利用曲线的方程绘制曲线的方法.如果想看看曲线是怎样绘制出来的,怎么办呢?编写简单的动画,就可以 ...

  2. JavaScript动画实例:曲线的绘制

    在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例.这些曲线都是根据其曲线方程,在[0,2π]区间取一系列角度值,根据给定角度值计算对应的各点坐标,然后在计算出 ...

  3. JavaScript动画实例:旋转的圆球

    1.绕椭圆轨道旋转的圆球 在Canvas画布中绘制一个椭圆,然后在椭圆上绘制一个用绿色填充的实心圆.之后每隔0.1秒刷新,重新绘制椭圆和实心圆,重新绘制时,实心圆的圆心坐标发生变化,但圆心坐标仍然位于 ...

  4. JavaScript动画实例:圆点的衍生

    考虑如下的曲线方程: R=S*sqrt(n) α=n*θ X=R*SIN(α) Y=R*COS(α) 其中,S和θ可指定某一个定值.对n循环取0~999共1000个值,对于每个n,按照给定的坐标方程, ...

  5. JavaScript动画实例:螺旋线

    数学中有各式各样富含诗意的曲线,螺旋线就是其中比较特别的一类.螺旋线这个名词来源于希腊文,它的原意是“旋卷”或“缠卷”.例如,平面螺旋便是以一个固定点开始向外逐圈旋绕而形成的曲线.在2000多年以前, ...

  6. JavaScript动画实例:动感小球

    已知圆的坐标方程为: X=R*SIN(θ) Y=R*COS(θ)     (0≤θ≤2π) 将0~2π区间等分48段,即设定间隔dig的值为π/24.θ初始值从0开始,按曲线方程求得坐标值(x,y), ...

  7. JavaScript动画实例:旋转的正三角形

    给定一个正三角形的重心坐标为(x0,y0),高为h,可以用如下的语句绘制一个底边水平的正三角形. ctx.beginPath(); ctx.moveTo(x0,y0-h*2/3); ctx.lineT ...

  8. JavaScript动画实例:沿五角星形线摆动的小圆

    五角星形线的笛卡尔坐标方程式可设为: r=10+(3*sin(θ*2.5))^2  x=r*cos(θ) y=r*sin(θ)              (0≤θ≤2π) 根据这个曲线方程,在[0,2 ...

  9. JavaScript动画实例:炸开的小球

    1.炸开的小球 定义一个小球对象类Ball,它有6个属性:圆心坐标(x,y).小球半径radius.填充颜色color.圆心坐标水平方向的变化量speedX.圆心坐标垂直方向的变化量speedY. B ...

随机推荐

  1. java实现测量到的工程数据

    [12,127,85,66,27,34,15,344,156,344,29,47,-] 这是某设备测量到的工程数据. 因工程要求,需要找出最大的 5 个值. 一般的想法是对它排序,输出前 5 个.但当 ...

  2. Java实现第十届蓝桥杯求和

    试题 A: 求和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包 括 1.2.9.10 至 32.39 和 40,共 28 个,他们的 ...

  3. Java实现第九届蓝桥杯方格计数

    方格计数 题目描述 如图p1.png所示,在二维平面上有无数个1x1的小方格. 我们以某个小方格的一个顶点为圆心画一个半径为1000的圆. 你能计算出这个圆里有多少个完整的小方格吗? 注意:需要提交的 ...

  4. java实现第四届蓝桥杯剪格子

    剪格子 题目描述 如图p1.jpg所示,3 x 3 的格子中填写了一些整数. 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是60. 本题的要求就是请你编程判定:对给定的m x n 的格子 ...

  5. Linux 递归acl权限和默认acl权限

    递归acl权限 递归acl指给父目录设定acl时,所有的子文件和子目录都拥有相同的acl权限 setfacl -m u:boduo:rx -R /project/ 默认acl权限 默认acl权限的作用 ...

  6. [C#.NET 拾遗补漏]02:数组的几个小知识

    阅读本文大概需要 1.5 分钟. 数组本身相对来说比较简单,能想到的可写的东西不多.但还是有一些知识点值得总结和知晓一  下.有的知识点,知不知道不重要,工作中用的时候搜索一下就可以了,毕竟实现一个功 ...

  7. 分布式ID总结

    分布式ID 生成的ID使用场景 几乎所有的业务系统,都有生成一个记录标识的需求,例如:message_id, order_id.这个记录标识往往就是数据库中的唯一主键,数据库上会建立聚集索引(clus ...

  8. sed中使用shell变量

    假设希望在 file_to_modified 文件最后新增一行以下信息:传入 shell 脚本文件的第一个参数,以及当前时间(YYYY-MM-DD HH:MMS) date "+%Y-%m- ...

  9. ubuntu安装mysql并使用Navicat连接

    今天配置了一下自己的服务器,发现网上很多教程都有点老,而且不是很全.干脆就写一篇Ubuntu安装mysql,并用Navicat连接的全流程 一.安装mysql 1. sudo apt-get inst ...

  10. ZWave对COMAND CLASS的处理流程

    文章主题  在开发一个 ZWave Device 的过程中,对 COMAND CLASS(单词太长了,后面就简写为 CC 啦) 的处理是最基本.最重要的工作.这篇文章以最最简单的 CC:COMMNAD ...