Hilbert2D.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Hilbert</title>
<style>
canvas {
padding : 5px
}
</style>
</head>
<body>
<script type="text/javascript" src="Hilbert.js"></script>
<script type="text/javascript">
/* ==================== SCRIPTS ==================== */
document.body.appendChild(hilbert(200, 200, 0, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 1, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 2, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 3, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 4, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 5, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 6, 'white', 'lime'));
document.body.appendChild(hilbert(200, 200, 7, 'white', 'lime'));
/* ==================== SCRIPTS ==================== */
</script>
</body>
</html>
Hilbert.js
/**
* ヒルベルト曲線が描かれた canvas を返します.
* @param width width
* @param height height
* @param iteration 計算繰り返し数
* @return canvas
*/
function hilbert(width, height, iteration, bg, fg) {
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
var x = width;
var y = 0;
var dx = width / (2 * Math.pow(2, iteration) -1);
var dy = height / (2 * Math.pow(2, iteration) -1);
/**
* A型の形状を描画する.
*
* ● 0 == step のとき
* ┌←─ (Start)
* ↓
* └→─ (End)
*
* ● 0 < step のとき
* A←D (Start)
* ↓
* A→B (End)
*/
var drawA = function(step) {
if (1 > step) {
moveLeft();
moveDown();
moveRight();
} else {
drawD(step-1); moveLeft();
drawA(step-1); moveDown();
drawA(step-1); moveRight();
drawB(step-1);
}
};
/**
* B型の形状を描画する.
*
* ● 0 == step のとき
* ┌→┐
* ↑ ↓
* │ │
*(S) (E)
*
* ● 0 < step のとき
* B→B
* ↑ ↓
* C A
*(S) (E)
*/
var drawB = function(step) {
if (1 > step) {
moveUp();
moveRight();
moveDown();
} else {
drawC(step-1); moveUp();
drawB(step-1); moveRight();
drawB(step-1); moveDown();
drawA(step-1);
}
};
/**
* C型の形状を描画する.
*
* ● 0 == step のとき
* (End) ─←┐
* ↑
* (Start) ─→┘
*
* ● 0 < step のとき
* (End) D←C
* ↑
* (Start) B→C
*/
var drawC = function(step) {
if (1 > step) {
moveRight();
moveUp();
moveLeft();
} else {
drawB(step-1); moveRight();
drawC(step-1); moveUp();
drawC(step-1); moveLeft();
drawD(step-1);
}
};
/**
* D型の形状を描画する.
*
* ● 0 == step のとき
*(E) (S)
* │ │
* ↑ ↓
* └←┘
*
* ● 0 < step のとき
*(E) (S)
* C A
* ↑ ↓
* D←D
*/
var drawD = function(step) {
if (1 > step) {
moveDown();
moveLeft();
moveUp();
} else {
drawA(step-1); moveDown();
drawD(step-1); moveLeft();
drawD(step-1); moveUp();
drawC(step-1);
}
};
var moveUp = function() {
y -= dy;
move();
}
var moveDown = function() {
y += dy;
move();
};
var moveRight = function() {
x += dx;
move();
};
var moveLeft = function() {
x -= dx;
move();
};
var move = function() {
ctx.lineTo(x, y);
};
ctx.fillStyle = bg;
ctx.fillRect(0,0,width,height);
// Path開始
ctx.beginPath();
ctx.strokeStyle = fg;
ctx.lineWidth = 1;
ctx.moveTo(x, y);
drawA(iteration);
ctx.stroke();
return canvas;
}