読者です 読者をやめる 読者になる 読者になる

JavaScript でヒルベルト曲線を描く

Ruby/Tk のプログラム(参照)を移植しました。

次数:


HTML

<form id="fm">
<p>次数:
<select name="dim">
<option value="1">1</option><option value="2">2</option>
<option value="3" selected>3</option><option value="4">4</option>
<option value="5">5</option><option value="6">6</option>
</select>
<input type="button" value="描画" onclick="main()">
</p>
</form>
<canvas id="myCanvas" width="400" height="400" style="background-color: ghostwhite;"></canvas>

JavaScript

function main() {
  var canvas = document.getElementById('myCanvas');
  field = canvas.getContext('2d');
  
  var n = fm.dim.value;  //次数
  field.clearRect(0, 0, 400, 400);
  
  var width = 400;
  lgth = width / Math.pow(2, n);
  y = (width - lgth * (Math.pow(2, n) - 1)) / 2;  //見栄えを整えているだけで、特に意味のない計算
  x = width - y;
  
  field.beginPath();
  field.strokeStyle = "firebrick";
  field.lineWidth = 1;
  field.moveTo(x, y);
  ldr(n);
}

function ldr(n) {
  if (n == 0) return;
  dlu(n-1); x -= lgth; line();
  ldr(n-1); y += lgth; line();
  ldr(n-1); x += lgth; line();
  urd(n-1);
}

function urd(n) {
  if (n == 0) return;
  rul(n-1); y -= lgth; line();
  urd(n-1); x += lgth; line();
  urd(n-1); y += lgth; line();
  ldr(n-1);
}

function rul(n) {
  if (n == 0) return;
  urd(n-1); x += lgth; line();
  rul(n-1); y -= lgth; line();
  rul(n-1); x -= lgth; line();
  dlu(n-1);
}

function dlu(n) {
  if (n == 0) return;
  ldr(n-1); y += lgth; line();
  dlu(n-1); x -= lgth; line();
  dlu(n-1); y -= lgth; line();
  rul(n-1);
}

function line() {
  field.lineTo(x, y);
  field.stroke();
}