1. 程式人生 > 實用技巧 >JavaScript圖形例項:再談IFS生成圖形

JavaScript圖形例項:再談IFS生成圖形

在“JavaScript圖形例項:迭代函式系統生成圖形”一文中,我們介紹了採用迭代函式系統(Iterated Function System,IFS)建立分形圖案的一些例項。在該文中,仿射變換函式W的一般形式為

X1=a*X0 + b*Y0 + e

Y1=c*X0 + d*Y0 + f

給定不同的IFS碼,可以生成不同的圖形。

實際上,仿射變換函式的形式還可以是

X1= a * X0*cos(c/180) - b * Y0*sin(d/180) + e

Y1= a * X0*sin(c/180) + b * Y0*cos(d/180) + f

按這種仿射變換函式並給出相應的IFS碼,編寫如下的HTML程式碼。

<!DOCTYPE html>

<head>

<title>IFS生成圖形</title>

<script type="text/javascript">

function draw(id)

{

var canvas=document.getElementById(id);

if (canvas==null)

return false;

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

ctx.fillStyle="#EEEEFF";

ctx.fillRect(0,0,500,500);

ctx.fillStyle="red";

var a=[0.5,0.5,0.25,0.25];

var b=[0.5,0.5,0.25,0.25];

var c=[0,0,0,0];

var d=[0,0,0,0];

var e=[0,0.5,2.0,-1.0];

var f=[0,0,2.0,2.0];

var p=[0.2,0.2,0.3,0.3];

var x0=0;

var y0=0;

for (i=0; i<100000; i++)

{

r=Math.random();

if (r<=p[0])

index=0;

else if (r<=p[0]+p[1])

index=1;

else if (r<=p[0]+p[1]+p[2])

index=2;

else

index=3;

x1=a[index]*x0*Math.cos(c[index]/180)-b[index]*y0*Math.sin(d[index]/180)+e[index];

y1=a[index]*x0*Math.sin(c[index]/180)+b[index]*y0*Math.cos(d[index]/180)+f[index];

ctx.fillText('.',x1*100+200,400-y1*100);

x0 = x1;

y0 = y1;

}

}

</script>

</head>

<body onload="draw('myCanvas');">

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

</canvas>

</body>

</html>

在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中繪製出如圖1所示的王冠圖案。

圖1 王冠

將上面程式中的IFS碼定義改寫為:

var a=[0.2,0.2,0.2,0.2,0.85];

var b=[0.2,0.2,0.2,0.2,0.85];

var c=[0,0,0,0,100];

var d=[0,0,0,0,100];

var e=[0.7,-0.7,0,0,0];

var f=[0,0,0.7,-0.7,0];

var p=[0.2,0.2,0.2,0.2,0.2];

由於有5個變換函式,適當新增一個條件選擇語句,可在瀏覽器視窗中繪製出如圖2所示的萬花筒圖案。

圖2 萬花筒

實際上,還可以採用1種變換函式進行迭代變換,生成有趣的圖形。下面介紹環形圖案和窗花形圖案的迭代生成方法。

環形圖案的迭代變換公式為:

Xn+1=d*sin(a*Xn)-sin(b*Yn)

Yn+1=c*cos(a*Xn)+cos(b*Yn)

根據這個迭代公式,編寫如下的HTML程式碼。

<!DOCTYPE html>

<head>

<title>環形圖案</title>

<script type="text/javascript">

function draw(id)

{

var canvas=document.getElementById(id);

if (canvas==null)

return false;

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

ctx.fillStyle="#EEEEFF";

ctx.fillRect(0,0,500,500);

ctx.fillStyle="red";

var a=1.40;

var b=1.56;

var c=1.40;

var d=-6.56;

var x0=0;

var y0=0;

for (i=0; i<10000; i++)

{

x1=d*Math.sin(a*x0)-Math.sin(b*y0);

y1=c*Math.cos(a*x0)+Math.cos(b*y0);

ctx.fillText('.',x1*30+250,y1*30+200);

x0 = x1;

y0 = y1;

}

}

</script>

</head>

<body onload="draw('myCanvas');">

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

</canvas>

</body>

</html>

在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中繪製出如圖3所示的環形圖案。

圖3 環形圖案

窗花形圖案的迭代公式為:

Xn+1= Yn-sign(Xn)*|b*Xn-c|1/2

Yn+1= a-Xn

根據這個迭代公式,編寫如下的HTML程式碼。

<!DOCTYPE html>

<head>

<title>窗花形圖案</title>

<script type="text/javascript">

function draw(id)

{

var canvas=document.getElementById(id);

if (canvas==null)

return false;

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

ctx.fillStyle="#EEEEFF";

ctx.fillRect(0,0,500,500);

ctx.fillStyle="red";

var a=1;

var b=4;

var c=50;

var x0=0;

var y0=0;

for (i=0; i<100000; i++)

{

x1=y0-Math.sign(x0)*Math.sqrt(Math.abs(b*x0-c));

y1=a-x0;

ctx.fillText('.',x1+250,y1+200);

x0 = x1;

y0 = y1;

}

}

</script>

</head>

<body onload="draw('myCanvas');">

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

</canvas>

</body>

</html>

在瀏覽器中開啟包含這段HTML程式碼的html檔案,可以看到在瀏覽器視窗中繪製出如圖4所示的窗花形圖案。

圖4 a=1,b=4,c=50時繪製的圖案

同樣,迭代公式中的係數a,b,c作為IFS碼,取不同的值會生成不同的圖形。

例如,取a=0.4,b=1,c=50時,可以在瀏覽器視窗中繪製出如圖5所示的窗花形圖案。

圖5 a=0.4,b=1,c=50時繪製的圖案

例如,取a=0.4,b=1,c=50時,並修改“ctx.fillText('.',x1+250,y1+200);”為“ctx.fillText('.',x1*100+250,y1*100+200);”進行適當放大,可以在瀏覽器視窗中繪製出如圖6所示的圖案。

圖6 a=0.4,b=1,c=0時繪製的圖案