雪花曲線


雪花的遞迴繪圖基本圖案如下圖左所示,進一步的構圖如下圖右所示:



這只是個大致的繪圖,說明雪花的基本架構,但並不是很精確,在遞迴時起始位置還需用上一些數學運算,才能使雪花繪圖接近自然,這個部份請自行觀看示範程式中的原始碼,如下所示:
  • SnowCurve.java
package cc.openhome;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JApplet;

import static java.lang.Math.*;

public class SnowCurve extends JApplet {
private Turtle t = new Turtle();

public void init() {
setBackground(Color.black);
}

public void snow(double rad, double min, double ks) {
if (rad > min) {
double r = rad * (1 - ks) / (1 + ks);
snow(r, min, ks);
int n = (int) ceil(log(min / rad) / log(ks));
for (int i = 0; i < 6; i++) {
for (int j = 1; j < n; j++) {
t.warp(rad * (1 - pow(ks, j)));
snow(r * pow(ks, j), min, ks);
t.warp(-rad * (1 - pow(ks, j)));
}
t.turn(60.0);
}
} else {
t.pset(t.getCurrentX(), t.getCurrentY());
}
}

public void paint(Graphics g) {
g.setColor(Color.yellow);

t.setGraphics(g);
t.window(0, 0, getWidth(), getHeight());
t.view(0, 0, getWidth(), getHeight());
t.setPoint(300, 50);
t.setAngle(90.0);

int d = getHeight() / 8;
for (int i = 0; i < 20; i++) {
double x = d + (getWidth() - 2 * d) * random();
double y = d + 5 * d * random();
double r = 0.1 * d + 0.9 * d * random();
t.setPoint(x, y);
t.setAngle(90.0);
snow(r, 0.1, 0.5);
}
}
}

以下是使用HTML5 Canvas的方式(如果瀏覽器支援HTML5 Canvas,例如最新版的Firexfox、Chrome、IE9等,可以直接將下面的內容存為HTML或按下檔名連結,直接載入瀏覽器執行觀看結果:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=Big5" http-equiv="content-type">
<script type="text/javascript" src="js/turtle.js"></script>
<script type="text/javascript">
window.onload = function() {
function snow(rad, min, ks) {
if (rad > min) {
var r = rad * (1 - ks) / (1 + ks);
snow(r, min, ks);
var n = Math.ceil(
Math.log(min / rad) / Math.log(ks));
for(var i = 0; i < 6; i++) {
for(var j = 1; j < n; j++) {
turtle.warp(rad * (1 - Math.pow(ks, j)));
snow(r * Math.pow(ks, j), min, ks);
turtle.warp(-rad * (1 - Math.pow(ks, j)));
}
turtle.turn(60.0);
}
} else {
turtle.pset(turtle.currentX, turtle.currentY);
}
}

var canvas1 = document.getElementById('canvas1');
var context = canvas1.getContext('2d');
var turtle = new Turtle(context);

turtle.window(0, 0, canvas1.width, canvas1.height);

turtle.view(0, 0, canvas1.width, canvas1.height);
turtle.setPoint(300, 50);
turtle.setAngle(90);

var d = canvas1.height / 8;
for(var i = 0; i < 20; i++) {
var x = d + (canvas1.width - 2 * d) * Math.random();
var y = d + 5 * d * Math.random();
var r = 0.1 * d + 0.9 * d * Math.random();
turtle.setPoint(x, y);
turtle.setAngle(90);
snow(r, 0.1, 0.5);
}
};
</script>
</head>
<body>
<canvas id="canvas1" width="600" height="400"></canvas>
</body>
</html>

以下是Firefox下看到的結果: