12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お題は不問!Qiita Engineer Festa 2023で記事投稿!

Rustでマンデルブロ集合を作成する方法 その1 (Rust インストールから必要なクレートの準備、基本画像出力まで)

Last updated at Posted at 2023-07-09

いままでC#、C/C++のC系?でプログラムを作成してきたわけであるが、関数型の言語も学習すると良いことがあるという眉唾ものの記事を読んだ影響で純粋関数型言語Haskellもかじってみた。
そうこうしているうちにRustなる比較的新しい言語が登場していることにはうすうす感づいていた。どうせC++の延長のような言語なんだろうと少々高を括っていたのだか、どれどれ、と重い腰を上げて学習にとりかかってみると、どうもおかしい、変だ、難しい、一筋縄ではいかない言語だと痛感する。

これは!

関数型言語に近いと感じ、しかも高速に動作する。難しいかもしれないが、習得するのに値する言語と判断した。Rustを使いこなせるようになればC++もHaskellも不要になるかもしれない。(独断です)

先程、眉唾ものと書いたが記事は正しかった
Rustの出現は脅威ではあるが、それでもHaskell(関数型言語系)を学習することの重要性は変わらない。むしろRustを学ぶにおいて、事前にHaskellをやっていたことが理解を早めたといってよい。

新しい言語を学ぶには、なにより沢山のコードを書いてみるのが早道。といわけで定番?のマンデルブロ集合の画像を作成してみたわけである。

作成したコードは若干冗長であり、改善の余地は大いに存在する。

まずはなによりRustのセットアップ

すでにインストール済みの方は次のセクションに進むのだ。それ以外の方は...
Rustの公式 https://www.rust-lang.org/ja/tools/installに沿って
Rustをインストールだ。

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

次に cargo init コマンドを使って初期のパッケージを作成

mkdir -p rust-mandelbrot
cd rust-mandelbrot
cargo init

vscodeを使ってプロジェクトを開く

現在のところ最もRustの拡張機能が整っているIDEがvscodeなので、vscode利用を前提に進む。

code .

スクリーンショット 2023-07-08 16.07.50.png

cargoは自動的にgitの設定までやってくれる。
自動で作成されたmain.rsを試しに以下のように修正する。(コピー&ペーストでもよい)

println!("Hello, world!"); なる行が存在するが、消してしまってかまわない

use image::{ImageBuffer, Rgb, RgbImage};
use irospace::{converter::*, ColorConverterBuilder, HsvColor, RgbColor};
use itertools::Itertools;
use num::complex::Complex;

// 画像のサイズ 1000x1000
static SIZE: u32 = 1000;

fn main() {
    // 複素数が使えるかのテスト
    let test: num::Complex<f64> = Complex::new(0.0, 0.0);
    println!("複素数 {}", test);

    // 1000x1000の画像データを作成
    let plot_data: Vec<u32> = plot(SIZE);

    // PNG画像を作成
    let mut img: ImageBuffer<image::Rgb<u8>, Vec<u8>> = RgbImage::new(SIZE, SIZE);
    // HSVからRGBへの変換器を作成
    let converter = ColorConverterBuilder::new().from_hsv().to_rgb().build();

    // 1000x1000の x,y座標の組み合わせを作成
    let grid = (0..SIZE).cartesian_product(0..SIZE);
    // x,y座標に色を割り当てる
    grid.for_each(|x| {
        // 色を取得
        let color = plot_data[(x.0 * SIZE as u32 + x.1) as usize];
        // HSVの H に色を割り当てる
        let color_code = HsvColor::new(color as u16, 255, 255);
        // HSVからRGBへ変換
        let rgb: RgbColor = converter.convert(&color_code).unwrap();
        // 画像に色を割り当てる
        img.put_pixel(x.0, x.1, Rgb([rgb.r(), rgb.g(), rgb.b()]));
    });

    // 画像を保存
    img.save("out_image.png").unwrap();
}

// プロットするデータを作成
fn plot(size: u32) -> Vec<u32> {
    // 360色の色を割り当てる
    let ret: Vec<u32> = (0..(size * size)).map(|n| (n / size) % 360).collect();
    ret
}

次に上記で利用する外部クレートをADDするため以下のコマンドを実行する。

cargo add image add irospace itertools num

必要とした外部クレートは以下

  • image
    • png ファイルを作成するため
  • irospace
    • 色空間を操作するためHSVからRGBなど
  • itertools
    • 直積集合を表現するため (1000x1000のグリッド作成)
  • num
    • 今後利用する複素数を扱うため

準備ができたらvscodeのコンソールから以下のコマンドを実行すると
out_image.pngが出来上がる。

cargo run

out_image.png

out_image.png

いまは虹色だが plot 関数を修正していくことで最終的に以下の画像を生成する。

fractal.png

次回へ

12
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?