前回、rust nannouで1次元セルオートマトンを描くでRule90でセルオートマトンを描くっていうプログラムをしました。
今回は、それをカラー化してみましょう。
今回のソースコードの変更点は次の通り
- カラー化(hslでカラーを設定)
- モデルを配列からベクタにする
- 初期値をランダムにする
こんな感じでやってます。
では、変更含め見ていきましょう
前回のおさらい
前回の記事(rust nannouで1次元セルオートマトンを描く)を見てもらえると、ソースコードは載ってますが、おおざっぱに言うと
要素100個の配列を準備して、現在の状態から更新した状態を作って、っていうのを繰り返すコードになってます。
前回のまとめで、初期値をランダムにしたりカラーにしたらどう?っていう話をしたので、今回はそれを実装します。
一次元セルオートマトンのランダム&カラー化の手順
では、初期値のランダム、カラー化やっていきましょう。手順を順番に進めていきます。
カラー化をする
カラー化は、描画の部分に手を加えていきます。
for i in 0..model.life_1.len() {
if model.life_1[i] == 1 {
draw.rect()
.w_h(5.0, 5.0)
.x((i as f32) * 5.0 - 200.0)
.y(-5.0 * (f as f32) + 300.0)
.hsl((f as f32).sin(), 1.0, 0.5);
}
}
これが、加えた結果です。
最後の行に
.hsl((f as f32).sin(), 1.0, 0.5);
この1行を加えただけです。
カラーの表現方法っていうのはいくつかあります。rgbやhsl,hsv,hwb,カラーネームを指定する方法など、alphaを入れるとか入れないとか、いくつかあります。
今回はhslで指定してます。やり方は色々です。フレーム数を三角関数にぶっこんで、値変換するみたいなコードにしてます。
モデルを配列からベクタにする
この後、2,3で何するかっていうと、初期値をランダムにしていきたいんです。配列のまま、やっていってもいいんですが、今後の拡張性とか、作りやすさのために配列をベクタにします。
今までは
struct Model {
life_1: [u8; 100],
life_2: [u8; 100],
}
こんな感じで、配列で表現してました。
配列だと、要素の数を最初に定義したり、要素数に自由度がない。初期値を初期化するときにイテレーターを使いたい(配列でも使えるのかな?)ってのがあって、ベクタにします。
ベクタにするのはそんなに難しいことじゃないです。とっても簡単
struct Model {
life_1: Vec<u8>,
life_2: Vec<u8>,
}
これだけ、かたちはVecで、要素は<u8>ですよとしてあげればOK。超簡単
次にこれに合わせて、初期値の初期化、ランダムな初期値の代入をやっていきましょう
初期値をランダムにする
ランダムな数を入れる方法はいくつかあるんですが、例えば配列であれば、forまわして、ランダムな値を入れていく感じです。
今回は、せっかくvecにしたので、イテレーターを使って、mapを使ってやってみましょう。ベクタにしてイテレーター使うのは、先述の通り、要素の数の自由度が増すっていうのも一つです。
初期化のコードはこんな感じです。
let max_cell = 1000;
let life_1 = (0..max_cell)
.map(|_| {
if nannou::rand::random_range(0.0, 1.0) < 0.5 {
0
} else {
1
}
})
.collect();
let life_2 = (0..max_cell).map(|_| 0).collect();
Model { life_1, life_2 }
ランダムの生成方法が微妙だけど(笑)まぁいいや
life_1について、mapで中身は、ランダム0から1までのランダムな数を定義して、0.5未満だったら0、それ以外なら1を返す、それをゼロからmax_cellまでやって、コレクトしてlife_1に入れてよ。っていう構造です。
僕あんまり、イテレーター得意じゃなくて、練習のためにやりたいなと思ってて今回はそれにしてみました。
life_2ははゼロで埋め尽くす。っていうコードです。fill()っていう関数があるんだけど、うまく使えなくて、今回はmapでやりました。fill使えたらカッコよかったな。。
これで、初期値(life_1)にランダムの数をバッファであるlife_2を初期化できました。
このベクタにした都合上です。update関数の中の
model.life_1 = model.life_2;
っていう代入式が配列のころは、許されてたんですが、これが許されなくなったので
model.life_1 = model.life_2.clone();
っていう風に書き換えました。
まとめ
今回は、初期値をランダムにして、カラー化するっていうのをやりました。その中で、配列からベクタにしました。ベクタにするとmax_cellっていう変数を新たに作って、セルの数を自由に設定できるようにもしました。
配列でやってもいいけど、ベクタだとスライスもできるし、自由度が増すかな?と思います。それぞれ使いどころだと思うけどね。
色んなやり方で、実装できるので、配列でどうしてもやりたい!っていうのではれば、それでやってみてもいいと思います。
それぞれ、やり方はいっぱいありますので、是非チャレンジをしてみましょう
ではまた!
コメント