ライフゲーム #28
gen_mesh.gが生成するグラフには端がある。そのため、前回のような現象も起きる。
とはいえ無限の広がりをもったグラフは難しいので、
グラフの上端と下端、右端と左端のノードを繋いでトーラス面にするプログラムを作ってみる。
gen_torus.g
BEGIN { if (ARGC != 1) { printf(2, 'usage: gvpr -f gen_torus.g -a width,height [-o outfile]\n'); exit(0); } int w = xOf(ARGV[0]), h = yOf(ARGV[0]); if (w < 1 || h < 1) { printf(2, 'error: width and height must be positive integer: %d,%d\n', w, h); exit(0); } node_t gen_node(graph_t g, int x, int y) { return node(g, sprintf('%d,%d', x, y)); } void gen_edge(graph_t g, node_t n, int x, int y) { edge_sg(g, n, gen_node(g, x, y), ''); } graph_t g = graph('', 'U'); int x, y; for (y = 0; y < h; y++) { int yp = (y + 1) % h; for (x = 0; x < w; x++) { int xp = (x + 1) % w; node_t n = gen_node(g, x, y); gen_edge(g, n, xp, y == 0 ? h - 1 : y - 1); gen_edge(g, n, xp, y); gen_edge(g, n, xp, yp); gen_edge(g, n, x, yp); } } write(g); }
幅や高さを法とする剰余で表される座標系について隣接するノード全てにエッジを張ればいいだけなので、
ある意味、gen_mesh.gよりもシンプルに書ける。
ただ、この書き方では問題があって、全てのノードの次数を強制的に8にするため、
幅や高さが2以下の場合は、同じノード間に2本以上のエッジが張られてしまう。
例えば、
gvpr -f gen_torus.g -a 2,2 | neato -T png -o 2x2.png
のように。
用途上、幅や高さをそれほど小さくすることはないと思うので、
問題点は覚えておきつつとりあえずこのままにしておこう。