JavaScript动画实例:递归分形图动态展示
在“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动画实例:递归分形图动态展示的更多相关文章
- JavaScript动画实例:李萨如曲线
在“JavaScript图形实例:阿基米德螺线”和“JavaScript图形实例:曲线方程”中,我们学习了利用曲线的方程绘制曲线的方法.如果想看看曲线是怎样绘制出来的,怎么办呢?编写简单的动画,就可以 ...
- JavaScript动画实例:曲线的绘制
在“JavaScript图形实例:曲线方程”一文中,我们给出了15个曲线方程绘制图形的实例.这些曲线都是根据其曲线方程,在[0,2π]区间取一系列角度值,根据给定角度值计算对应的各点坐标,然后在计算出 ...
- JavaScript动画实例:旋转的圆球
1.绕椭圆轨道旋转的圆球 在Canvas画布中绘制一个椭圆,然后在椭圆上绘制一个用绿色填充的实心圆.之后每隔0.1秒刷新,重新绘制椭圆和实心圆,重新绘制时,实心圆的圆心坐标发生变化,但圆心坐标仍然位于 ...
- JavaScript动画实例:圆点的衍生
考虑如下的曲线方程: R=S*sqrt(n) α=n*θ X=R*SIN(α) Y=R*COS(α) 其中,S和θ可指定某一个定值.对n循环取0~999共1000个值,对于每个n,按照给定的坐标方程, ...
- JavaScript动画实例:螺旋线
数学中有各式各样富含诗意的曲线,螺旋线就是其中比较特别的一类.螺旋线这个名词来源于希腊文,它的原意是“旋卷”或“缠卷”.例如,平面螺旋便是以一个固定点开始向外逐圈旋绕而形成的曲线.在2000多年以前, ...
- JavaScript动画实例:动感小球
已知圆的坐标方程为: X=R*SIN(θ) Y=R*COS(θ) (0≤θ≤2π) 将0~2π区间等分48段,即设定间隔dig的值为π/24.θ初始值从0开始,按曲线方程求得坐标值(x,y), ...
- JavaScript动画实例:旋转的正三角形
给定一个正三角形的重心坐标为(x0,y0),高为h,可以用如下的语句绘制一个底边水平的正三角形. ctx.beginPath(); ctx.moveTo(x0,y0-h*2/3); ctx.lineT ...
- JavaScript动画实例:沿五角星形线摆动的小圆
五角星形线的笛卡尔坐标方程式可设为: r=10+(3*sin(θ*2.5))^2 x=r*cos(θ) y=r*sin(θ) (0≤θ≤2π) 根据这个曲线方程,在[0,2 ...
- JavaScript动画实例:炸开的小球
1.炸开的小球 定义一个小球对象类Ball,它有6个属性:圆心坐标(x,y).小球半径radius.填充颜色color.圆心坐标水平方向的变化量speedX.圆心坐标垂直方向的变化量speedY. B ...
随机推荐
- Java实现 LeetCode 62 不同路径
62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中 ...
- C#Winform中resx文件无效 找不到路径
问题由来 笔者因为更改了添加的图片的路径,再把路径改成图片所在的路径还是报resx文件无效,未能找到路径 问题原因 其实这个问题是因为对对象的引用修改了,但是resx文件中的应用还是没有修改.因为re ...
- Java实现第八届蓝桥杯拉马车
拉马车 题目描述 小的时候,你玩过纸牌游戏吗? 有一种叫做"拉马车"的游戏,规则很简单,却很吸引小朋友. 其规则简述如下: 假设参加游戏的小朋友是A和B,游戏开始的时候,他们得到的 ...
- ModelArts准备工作
说明: 本文是一个ModelArts准备工作文档,适用于初次使用ModelArts的用户.使用ModelArts之前,需要做如下工作:注册华为云账号.完成ModelArts全局配置.以及熟悉OBS相关 ...
- 如何让json_encode不转义斜杠
当服务器返回一些数据时需要返回一些地址,但是默认的json_code是会对 / 转义成 \/ 的处理... 解决办法: 1. 正则替换: echo str_replace("\\/" ...
- centos7上安装memcached以及PHP安装memcached扩展(二)
开始在 PHP 中使用 Memcached 前, 我们需要确保已经安装了 Memcached 服务,接下来安装 php-memcached 扩展. PHP Memcached 扩展安装 第一步:如果 ...
- pip应用实例
homepage 目录 1. 安装 1.1. 指定版本 1.2. 用户权限 1.3. 读取requirments.txt 1.4. 不使用缓存文件 1.5. 指定extras_require 2. 镜 ...
- windows下Python版本切换使用方法
由于历史原因,Python有两个大的版本分支,Python2和Python3,又由于一些库只支持某个版本分支,所以需要在电脑上同时安装Python2和Python3,因此如何让两个版本的Python兼 ...
- UDF_表值函数与标量函数的区别_分割字符串成单个的字符并返回表(插入到表中)
UDF_区别_分割字符串成单个的字符并返回表(插入到表中) /* SQL表值函数和标量值函数的区别 实验环境:SQL Server 2014,参考maomao365有改编 在sqlserver中存储过 ...
- 重装conda
重装Conda是因为想重装tensorflow,结果竟然报了各种各样稀奇古怪的错误:我贴一下自己见过的报错 The environment is inconsistent, please check ...