2012-01-01から1ヶ月間の記事一覧

ライフゲーム #26

せっかくだからもう少しだけset_gen0.gを便利にしてみよう。 座標リストと移動量の組み合わせを複数指定できるようにしてみる。 set_gen0.g BEGIN { if (ARGC < 1) { printf(2, 'usage: gvpr -cf set_gen0.g -a filename [[-a x0,y0 -a filename]...] [-a x0…

ライフゲーム #25

メッシュをはみ出してしまうような設定が行われた場合は警告を出すようにすべきか? 現状、はみ出してしまうような座標が指定されても無視するだけなので問題は少ないが。 set_gen0.g BEGIN { ...snip int fd = openF(filename, 'r'); string p[], s; int pn…

ライフゲーム #24

第0世代のalive属性付きノードを設定するgvprフィルタset_gen0.gで使い辛い点は、 設定座標リストファイルで指定できるメッシュ座標が絶対座標であることだ。 パターン全体を平行移動して設定したいことはよく起きるので、 座標リストは相対座標であることに…

大寒と節分の間、毎日寒いです。

無向グラフのDOTにgvprでrank付きサブグラフを加える #3

とりあえず前回のコードでうまくrankの設定がなされたサブグラフが加えられた。 しかし、insert_rank.gが出力するDOTを見ると、 graph { subgraph 3 { graph [rank=same]; "2,3"; "1,3"; "0,3"; } subgraph 2 { graph [rank=same]; ...snip のように、subgra…

無向グラフのDOTにgvprでrank付きサブグラフを加える #2

DOTにおけるサブグラフの定義の順序は、サブグラフが新規に作成されてグラフに追加される順序である。 それは前回のコードでは各ノードが走査される順序に依存していた。 前回は走査順が0,1,2,3になっていたが、順序は与えられるグラフ次第なので、しっかり…

無向グラフのDOTにgvprでrank付きサブグラフを加える #1

話題のメインがライフゲームと関係なさそうなのでタイトルを変えた。 ライフゲームの記事の#20ではdotコマンドを使ってレンダリングしようとした。 その時は手書きでDOTファイルを書いたのだが、あのサイズでもそれは面倒だった。 これをメッシュ生成プログ…

朝、雪が積もっていた。 積もってるというよりも凍っていた。 夜までにほとんど融けてしまったが。

ライフゲーム #23

diehard.txtで設定されるパターンはDiehardという名前が付けられている。 第0世代でたった7個しかaliveでないのだが130世代ほど変化が続き、Methuselah*1と呼ばれるカテゴリに属する。 McClane警部補はまだ一般人な方で、Methuselahの中にはもっとずっと長く…

ライフゲーム #22

前日にdotで使用するために検討した際の見栄えがシンプルでいい感じだったので、 vis_alive.gをそういう感じに描画されるように変更してみた。 vis_alive_2.g BEGIN { if (ARGC != 1) { printf(2, 'usage: gvpr -f vis_alive_2.g -a size\n'); exit(0); } do…

ライフゲーム #21

グラフの見栄えに関するパラメータを調節してそれっぽくなるようにしてみる。 とりあえず、パラメータをtest.gvに直接挿入して調整してみる。 test.gv graph { graph [nodesep=0,ranksep=0]; { rank = same; "0,3"; "1,3"; "2,3"; } ...snip "1,3" -- "2,2";…

ライフゲーム #20

グラフのレンダリングにneatoを使ってきたがdotを使えないか考えてみた。 pos属性は便利だがneatoに特異的な属性なのでdotでは使えない。 代わりにノードの位置揃えにrank属性があり、これを使うことにする。 test.gv graph { { rank = same; "0,3"; "1,3"; …

ライフゲーム #19

Glider Gunの動きを100世代分ほどのanimated GIFにしてみる。 このサイズで100世代分のDOTとPNGを生成するのにあまり速くない手元の環境で二分程度なので速度的に遅すぎる訳ではない。 レンダリングに時間がかかるようだ。 やっていることがGraphviz本来の使…

ライフゲーム #18

第0世代のalive属性を長々と設定するところをもう少し何とかしよう。 glider_gun.txt 1,23 1,24 2,23 2,24 ...snip 35,25 35,26 36,25 36,26のようにalive属性を付与するノード名のリストを作成しておく。 このリストを読み込み、name属性がそのどれかに一致…

ライフゲーム #17

次に、画像化用の属性を付与するフィルタvis_alive.gを変更する。 vis_alive.g BEGIN { if (ARGC != 1) { printf(2, 'usage: gvpr -cf vis_alive.g -a size\n'); exit(0); } double size = ARGV[0]; if (size <= 0) { printf(2, 'error: size must be positi…

ライフゲーム #16

そういえば、gen_mesh.gが出力するものと似たようなグラフを、 Graphvizのgvgenコマンドにグリッド生成オプションを与えて、 gvgen -g 3,4 | neato -Elen=.75 -T png -o 3x4.png のように生成することはできる。 しかし、ノード名が1から始まる連番となって…

ライフゲーム #15

今までのコードを少し変更、整理してみる。 ノードのname属性を"nx_y"形式から"x,y"形式に変更する。 また、vis_alive.gにneatoでオプション指定していたものを組み入れる。 次世代を生成するnext_gen.gは触る必要は多分ないはず。まず、メッシュ生成プログ…

ライフゲーム #14

前の記事で示したコードの中に少しくどい部分があった。 pos属性をピン留めするために感嘆符を付加するコード、 c:\foo> gvpr -cf vis_alive.g glider_0.gv | gvpr -c "N{pos=sprintf('%s!',pos);}" | ...snip...は、posがstringなので、 c:\foo> gvpr -cf v…

ライフゲーム #13

さて、ノードのpos属性をピン留めする方向に進むか否かについて考えてみよう。 ピン留めしていない現在のグラフでは各ノードのpos属性の値は1単位で整数値を与えられている。 ピン留めされていないため、neatoのオプションで、 neato ...snip... -Nwidth=.2 …

ライフゲーム #12

コマ撮りでは面白みに欠けるので動画にしてみよう。 はてなで使える形式で大抵のグラフィカルなウエブブラウザで見られるものとなるとanimated GIFか。 手元にある環境でお手軽に作成するなら、Ubuntuの方にImageMagickを入れてあったのでこれを使う。 まず…

ライフゲーム #11

広くなった空で動かしてみよう。 既述の通り、コマンドラインシェルにあまり関係しないようgvprプログラムをシェルスクリプト代わりにする。 第0世代から第49世代まで7世代ごとの状況を画像化してみる。 gvpr "BEGIN{int i;for(i=0;i<49;i++)system(sprintf(…

ライフゲーム #10

6x6ではあんまりなのでGliderをもうちょっとだけ広い空で滑空させる。 メッシュサイズを20x16にして第0世代のグラフを今まで通りの方法で作る。 gvpr -f gen_mesh.g -a "20 16" | gvpr -c "N{if(name=='n16_2'||name=='n16_3'||name=='n17_1'||name=='n17_3'…

gvprでシェルスクリプト代わり

思いました。 gvprプログラムに任せることでbashかcmdかなんてことはあまり気にしなくて済むではないか、と。 Graphvizで閉じる方針もここまでくるともう何だか無理矢理くさい。 gvpr "BEGIN{int i;for(i=0;i<4;i++)system(sprintf('gvpr -cf next_gen.g gli…

ライフゲーム #9

Gliderパターンの第0世代を作ってみる。 gvpr -f gen_mesh.g -a "6 6" | gvpr -c "N{if (name=='n2_2'||name=='n2_3'||name=='n3_2'||name=='n3_4'||name=='n4_2'){alive=1;}}" > glider_0.gvgen_mesh.gが生成したものを一旦ファイルに落とし、 テキストエデ…

ライフゲーム #8

Blinkerばかりで飽きたので別のパターンにしたい。 が、その前に、第0世代のDOTファイルのエッジ群をいちいち手で構成するのはさすがに面倒なので、 以前言及したように、メッシュサイズを与えるとエッジ構成を自動生成するプログラムを作成する。 その生成…

ライフゲーム #7

さらにデザインをリファインしてみる。 pos属性を与えることでノード位置が固定されているので、 ノード名を表示して確認する必要もないだろう。 また、エッジも明示する必要もあまり感じない。 この辺りを考慮することでもっと図をコンパクトにする。 gvpr …

ライフゲーム #6

どうも斜めになっているのが少し気になる。 ノード名がメッシュ上での座標としているので、これを利用してノードにpos属性を与えてみる。 gvpr -c -f vis_alive.g blinker_0.gv | gvpr -c "N{int x,y;sscanf(name,'n%d_%d',&x,&y);pos=sprintf('%d,%d',x,y);…

ライフゲーム #5

blinker_0.gvがどう遷移していくか見てみる。 next_gen.gで第0世代(blinker_0.gv)から始めて第1、第2世代のグラフを順番に生成する。 gvpr -c -f next_gen.g -o blinker_1.gv blinker_0.gv gvpr -c -f next_gen.g -o blinker_2.gv blinker_1.gvこれらのグ…

ライフゲーム #4

blinker_0.gvを視覚化してみる。 dot -Gsize=8 -Tpng -oblinker_0.png blinker_0.gvサイズ指定をしないとちょっと大きいのでデフォルトよりも少し小さ目で出力した。 このレイアウトはあまりおいしくない。 ということでdotでなくneatoを使う。 gvpr -c "N[a…

ライフゲーム #3

前述のテストデータでは単純すぎるので、 それより少しだけ複雑な、でも分かりやすいものを作成してみる。 blinker_0.gv graph { n0_0 -- n0_1 -- n0_2 -- n0_3 -- n0_4; n1_0 -- n1_1 -- n1_2 -- n1_3 -- n1_4; n2_0 -- n2_1 -- n2_2 -- n2_3 -- n2_4; n3_0…