LoginSignup
18
18

More than 5 years have passed since last update.

フラクタルで木を書く

Posted at

そういえば書いたことなかったのでやってみた。

概念

  • 何度再帰するか決める(depth)
  • 座標を指定する(x1, y1)
  • 方向を指定する(θ)
  • x1, y1から、その方向に線を引く(x2, y2)
  • 再帰回数が残っていれば、引いた先(x2, y2) から、任意の角rとして θ-r, θ+r方向へ線を引く

コード

注意: 伸ばす長さ、角度に乱数が入っている

{sin, cos, PI} = Math

drawLine = (ctx, p1, p2) ->
  ctx.beginPath();
  ctx.strokeStyle = 'gray'
  ctx.moveTo(p1.x, p1.y);
  ctx.lineTo(p2.x, p2.y);
  ctx.stroke();

drawTree = (
  ctx     # canvas context
  x1, y1  # position
  len     # length of node
  stand   # current dir
  depth   # recursion count
) ->
  rl = Math.abs(0.5 - Math.random()) * len
  x2 = x1 + rl * cos(stand)
  y2 = y1 + rl * sin(stand)
  drawLine(ctx, {x: x1, y: y1}, {x: x2, y: y2})
  if depth > 0
    diffdir = Math.random() * PI / 6
    drawTree(ctx, x2, y2, len, stand + diffdir, depth-1)
    drawTree(ctx, x2, y2, len, stand - diffdir, depth-1)

window.addEventListener 'load', ->
  canvas = document.createElement 'canvas'
  canvas.width=800
  canvas.height=600
  document.body.appendChild(canvas)
  ctx = canvas.getContext('2d')
  for x in [1..30]
    drawTree(ctx, 600*Math.random(), 400*Math.random(), 20, -PI/2, 8)

結果

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18