1. 程式人生 > 實用技巧 >JavaScript動畫例項:遞迴分形圖動態展示

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曲線的動態生成