Koch曲線的構造過程是:取一條長度為L0的直線段,將其三等分,保留兩端的線段,將中間的一段改換成夾角為60度的兩個等長直線;再將長度為L0/3的4個直線段分別進行三等分,並將它們中間的一段均改換成夾角為60度的兩段長為L0/9的直線段;重覆以上操作直至無窮,可得以一條具有自相似結構的折線,如圖1所 ...
Koch曲線的構造過程是:取一條長度為L0的直線段,將其三等分,保留兩端的線段,將中間的一段改換成夾角為60度的兩個等長直線;再將長度為L0/3的4個直線段分別進行三等分,並將它們中間的一段均改換成夾角為60度的兩段長為L0/9的直線段;重覆以上操作直至無窮,可得以一條具有自相似結構的折線,如圖1所示。
圖1 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 =5;
var curdepth = 0;
ctx.lineWidth = 2;
Koch({x:50,y:150},{x:550,y:150},Math.PI/3);
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()
}
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在瀏覽器視窗中繪製出的Koch曲線,如圖2所示。
圖2 遞歸深度maxdepth =5的Koch曲線
由圖1和2可知,Koch曲線的初始圖元是直線,但最終結果卻是一條參差不齊的曲線,很像雪花的邊緣,如果將3條這樣的曲線圍在一起,便得到Koch雪花的圖案。這樣,初始圖元不是一條直線,而是一個等邊三角形。Koch雪花的生成示例如圖3所示。
圖3 Koch雪花的生成
在程式設計時,定義好等邊三角形的三個頂點坐標,調用三次Koch遞歸過程,以實現等邊三角形三條邊各自的Koch曲線生成,即可得到Koch雪花圖案。編寫的HTML文件如下。
<!DOCTYPE html>
<head>
<title>Koch雪花</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 maxdepth =5;
var curdepth = 0;
ctx.lineWidth = 2;
Koch({x:50,y:450},{x:500,y:450},Math.PI/3);
Koch({x:275,y:450-225*Math.sqrt(3)},{x:50,y:450},Math.PI/3);
Koch({x:500,y:450},{x:275,y:450-225*Math.sqrt(3)},Math.PI/3);
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()
}
</script>
</body>
</html>
在瀏覽器中打開包含這段HTML代碼的html文件,在瀏覽器視窗中可能會繪製出如圖4所示的Koch雪花圖案。
圖4 遞歸深度maxdepth =5的Koch雪花圖案