在“JavaScript圖形實例:迭代函數系統生成圖形”一文中,我們介紹了採用迭代函數系統(Iterated Function System,IFS)創建分形圖案的一些實例。在該文中,仿射變換函數W的一般形式為 X1=a*X0 + b*Y0 + e Y1=c*X0 + d*Y0 + f 給定不同的I ...
在“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時繪製的圖案