RustにいればRustに従え(6) 吉例mandelbrot集合を描く、mut無、for2

Joseph Halfmoon

前回そろそろRustも入出力とか地道なところを練習しないといろいろできないじゃん、と痛感しました。そこで画像出力をやってみることに。題材は吉例「マンデルブロ集合を描く」であります。流石に画像出力はmutいるだろ~と思ったらアカラサマなmut無で書けてしまいました。流石にFOR文は2つ。

※『RustにいればRustに従え』関係記事 index はこちら

※動作確認は、Windows11のWSL2上にインストールしたUbuntu20.04LTS上のrustc 1.64.0 (a55dd71d5 2022-09-19) で行っています。

Mandelbrot集合

多分、太古の時代から数限りなく描かれてきたマンデルブロ集合こそは、フラクタル世界へいざなう、マンデルブロ様のご発案であります。折り重なるような多数の先行プログラムがある中で、今回下敷きといたしましたのは、以下投稿にて「Go言語」で自作いたしましたるプログラムであります。

やっつけな日常(7) スマホでGo!fmt.Printで吉例マンデルブロ集合を描く

上記を合わせてみていただくと、Go言語とRust言語の違いというかなんというかが分かるかも知れません。ホントか?眉唾。

マンデルブロ集合の計算そのものは大して難しくありません。淡々と計算を繰り返すのみ。ただ、画像出力が必要なだけにそこだけが問題と。そこで上記例では古くよりUnix世界で使われている ppm フォーマットを使用しています。テキストファイルで画像が出力できるもの。テキストなので出来上がった画像のファイルサイズはデカいですが、なんとなれば print! マクロのみでも画像出力が可能。全然、入出力の練習になってないじゃん!

ppmフォーマットの画像を表示できるような画像ビューワーがあればよいですが、ない場合には「定番ツール」Imagemagickをインストールしてあれば、convert コマンドでお好みのバイナリ画像フォーマットに変換可能であります。

今回実験のソースコード

今回実験のソースは以下のとおり、これ以外に何も画像出力のためのライブラリなど使用しておりませぬ。

fn mandelbrot(pa: f64, pb: f64, x: f64, y: f64, r: f64, cnt: i32) -> i32 {
    if cnt > 999 || r > 100.0 {
        return cnt;
    }
    let xn = x * x - y * y + pa;
    let yn = 2.0 * x * y + pb;
    let r = xn * xn + yn * yn;
    return mandelbrot(pa, pb, xn, yn, r, cnt + 1);
}

fn draw_mandelbrot(pa: f64, pb: f64) {
    match mandelbrot(pa, pb, 0.0, 0.0, 0.0, 0) {
        20 ..=999 => println!("255 255 255"),
        15 ..=19 => println!("200 200 120"),
        10 ..=14 => println!("150 150 120"),
        5 ..=9 => println!("100 100 120"),
        3 ..=4 => println!("60 60 120"),
        0 ..=2 => println!("10 10 80"),
        _ => println!("0 0 0"),
    }
}

fn main() {
    let n_size: usize = 200; // Picture size
    let pa = (1..=n_size).map(|i| -1.5 + i as f64 / 100.0);
    let pb = (1..=n_size).map(|i| 1.0 - i as f64 / 100.0);
    println!("P3");
    println!("{0} {1}", n_size, n_size);
    println!("256");
    for xa in pa {
        for yb in pb.clone() {
            draw_mandelbrot(xa, yb);
        }
    }
}
実験結果

プロジェクトフォルダ内で、以下のようにすれば n_size (上記では200)で指定された正方形の画面にマンデルブロ集合が出力されます。

$ cargo run >mandel.ppm

冒頭のアイキャッチ画像は直接 ppm 画像を表示できるツールNkV(ホンダ様作)を使わせていただいとります。Imagemagickがインストールしてあれば、以下のようにすれば、png形式などへの変換も簡単。ファイルサイズはビックリするくらい小さくなります。

$ convert mandel.ppm mandel.png

マンデルブロ集合くらいアカラサマな mut 無で行ける。それがどうした。

RustにいればRustに従え(5) FIRフィルタの実体たった1行?mut無、for最小 へ戻る

RustにいればRustに従え(7) Pascalの三角形を計算、mut無、for 1 へ進む