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

Ruby/Tk でヒルベルト曲線を描く

Ruby/Tk でヒルベルト曲線(ペアノ曲線)を描いてみました。ここC言語用のプログラムを移植しただけです。元記事の著者に感謝いたします。

下は 5次のヒルベルト曲線です。7次くらいが限度だと思います。

ヒルベルト曲線

# encoding: Shift_JIS
require 'tk'

class Draw
  Width = 400
  
  def initialize(n)
    @lgth = Width / 2 ** n
    @y = (Width - @lgth * (2 ** n - 1)) / 2  #見栄えを整えているだけで、特に意味のない計算
    @x = Width - @y
    @oldx = @x; @oldy = @y
    
    @canvas = TkCanvas.new do
      width(Width); height(Width)
      background("ghostwhite")
      pack
    end
  end
  
  def ldr(n)
    return if n == 0
    dlu(n-1); @x -= @lgth; line
    ldr(n-1); @y += @lgth; line
    ldr(n-1); @x += @lgth; line
    urd(n-1)
  end
  
  def urd(n)
    return if n == 0
    rul(n-1); @y -= @lgth; line
    urd(n-1); @x += @lgth; line
    urd(n-1); @y += @lgth; line
    ldr(n-1)
  end
  
  def rul(n)
    return if n == 0
    urd(n-1); @x += @lgth; line
    rul(n-1); @y -= @lgth; line
    rul(n-1); @x -= @lgth; line
    dlu(n-1)
  end
  
  def dlu(n)
    return if n == 0
    ldr(n-1); @y += @lgth; line
    dlu(n-1); @x -= @lgth; line
    dlu(n-1); @y -= @lgth; line
    rul(n-1)
  end
  
  def line
    TkcLine.new(@canvas, @oldx, @oldy, @x, @y, 'fill' => 'firebrick')
    @oldx = @x; @oldy = @y
  end
end

TkRoot.new do
  title("ヒルベルト曲線")
end

n = (ARGV[0] || 3).to_i  #次数を引数に。デフォルトは3次
exit if n < 1
Draw.new(n).ldr(n)

Tk.mainloop

次数を引数にします(デフォルトは 3次)。エンコーディングは適当に修正して下さい。

※追記 JavaScript バージョンはこちらです。Green Shoes バージョンはこちら