引き続き、ヴィジュアライズしたい。
ビジュアライズに限れば適当なplotを使えば良いのだろうけど、gifも欲しい。
どうもその適当なplotで十分GIF生成もできる様なのでお試し。
Gnuplot
ruby bindingがgemにあるのでinstall.
サンプルはあるがドキュメントは無いせいか、イマイチ使いにくい。
ソースを見てみるとやってることはシンプルで、薄いラッパー。
gnuplotコマンドに文字列を流し込んでいるだけ。
set term gif animate
と相性が悪いだけで、他の用途なら問題無い気もする。
make_gif
set term gif animate
として、output先のファイル設定して、plotを繰り返せばアニメーションGIFに。
gnuplot_make_gif.rb
require "gnuplot"
def make_gif(name = "",x = 0,y = 0,fps = 0, &f)
Gnuplot.open { |g|
g << "set nokey\n"
g << "set term gif animate\n"
g << "set output \"#{name}\"\n"
g << "set xrange [-1:#{x+1}]\n"
g << "set yrange [-1:#{y+1}]\n"
g << "set style line 1 lc \"green\" pt 7 ps 1\n"
(1..fps).each { |n|
cs = f.call(g,n)
g << "plot \"-\" with points ls 1\n#{cs}"
}
}
end
lifegame
plotに渡すデータへ二次元配列を変換。ちょいめんどい。
require "./gnuplot_make_gif.rb"
require "./lifegame.rb"
lg = Lifegame.new(300,300)
lg.random
make_gif("gnuplot_lifegame.gif",300,300,100) { |io,n|
io << "set style line 1 lc \"green\" pt 7 ps 0.25\n"
io << "set title \"lifegame:#{n}\"\n"
cs = lg.cells.map.with_index { |cy,iy|
cy.map.with_index { |cx,ix|
if cx == 1
"#{ix} #{iy}"
else
nil
end
}.select { |a| a != nil }.join("\n")
}.join("\n")
cs << "\ne\n"
lg.apply
cs
}
end
この300*300*100のGIF生成に、私のPCでは70秒ほどかかります。
座標変換のコストがちょいかかってます。