Ruby-Processing ブレゼンハムのアルゴリズム

  • 5
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ブレゼンハムアルゴリズム を参考にさせていただいて、Ruby-Processing で実装してみました。

bresenham.gif

bresenham.rb
load_library :vecmath

# 参考
#
# プレゼンハムアルゴリズム
# http://aidiary.hatenablog.com/entry/20050402/1251514618

def setup
  size 400, 400
end

# プレゼンハムアルゴリズムを用いて
# fm から to へのラインを求める
def build_line(fm, to)
  next_x = fm.x
  next_y = fm.y
  delta_x = to.x - fm.x
  delta_y = to.y - fm.y

  step_x = delta_x < 0 ? -1 : 1
  step_y = delta_y < 0 ? -1 : 1

  delta_x = (delta_x * 2).abs
  delta_y = (delta_y * 2).abs

  line =[Vec2D.new(next_x, next_y)]

  if delta_x > delta_y
    fraction = delta_y - delta_x / 2
    while next_x != to.x
      if fraction >= 0
        next_y += step_y
        fraction -= delta_x
      end
      next_x += step_x
      fraction += delta_y
      line << Vec2D.new(next_x, next_y)
    end
  else
    fraction = delta_x - delta_y / 2
    while next_y != to.y
      if fraction >= 0
        next_x += step_x
        fraction -= delta_y
      end
      next_y += step_y
      fraction += delta_x
      line << Vec2D.new(next_x, next_y)
    end
  end
  line
end

def draw
  background 255

  translate width/2, height/2

  n = 15 # ドットひとつ分のサイズ
  rows = height / n
  cols = width / n

  rect_mode CENTER
  no_fill
  stroke 60
  for i in 0..rows
    for j in 0..cols
      rect (j-cols/2) * n, (i-rows/2) * n, n, n
    end
  end

  x = mouse_x - width/2 + n/2
  y = mouse_y - height/2 + n/2
  fm = Vec2D.new(0, 0)
  to = Vec2D.new(x / n, y / n)
  line = build_line(fm, to)
  if line
    fill(100)
    line.each {|v|
      rect v.x * n, v.y * n, n, n
    }
  end

  # マウスの位置まで line() で直線描画(ブレゼンハムアルゴリズムとの比較用)
  stroke 0x28, 0x28, 0xcc
  stroke_width 2
  line 0, 0, mouse_x - width/2, mouse_y - height/2
  stroke 0
  stroke_width 1
end

コマンドラインから次のように実行します。

$ rp5 run bresenham.rb

リンク