「2.7 プロジェクト:マンデルブロ集合のレンダリング」です。
use num::complex::Complex; fn calculate_mandelbrot( max_iters: usize, x_min: f64, x_max: f64, y_min: f64, y_max: f64, width: usize, height: usize, ) -> Vec<Vec<usize>> { let mut rows: Vec<_> = Vec::with_capacity(width); for img_y in 0..height { let mut row: Vec<_> = Vec::with_capacity(height); for img_x in 0..width { let x_percent = img_x as f64 / width as f64; let y_percent = img_y as f64 / height as f64; let cx = x_min + (x_max - x_min) * x_percent; let cy = y_min + (y_max - y_min) * y_percent; let escaped_at = mandelbrot_at_point(cx, cy, max_iters); row.push(escaped_at); } rows.push(row); } rows } fn mandelbrot_at_point(cx: f64, cy: f64, max_iters: usize) -> usize { let mut z = Complex { re: 0.0, im: 0.0 }; let c = Complex::new(cx, cy); for i in 0..=max_iters { if z.norm() > 2.0 { return i; } z = z * z + c; } return max_iters; } fn render_mandelbrot(escape_vals: Vec<Vec<usize>>) { for row in escape_vals { let mut line = String::with_capacity(row.len()); for column in row { let val = match column { 0..=2 => ' ', 3..=5 => '.', 4..=10 => ':', 11..=30 => '*', 31..=100 => '+', 101..=200 => 'x', 201..=400 => '$', 401..=700 => '#', _ => '%', }; line.push(val) } println!("{}", line); } } fn main() { let mandelbrot = calculate_mandelbrot(1000, -2.0, 1.0, -1.0, 1.0, 80, 24); render_mandelbrot(mandelbrot); }
60行と長くなってきましたが、Github copilot君も手伝ってくれるので、写経する分にはサクサクで楽しい感じです。 「rustはコンパイルを通すまでがつれえ」という噂はまだ味わえないようです。
本に載っている実行サンプルだと・
みたいな真ん中に点が表示されています。
英語にそんな記号ないと思うのですか、何を表示しているのでしょうか?
ソースコードは?
を指定していて、雰囲気が違うので:
にしてみました。
警告
19行目の()
が冗長だと警告が出ました。
warning: unnecessary parentheses around assigned value --> src\main.rs:16:29 | 16 | let x_percent = (img_x as f64 / width as f64); | ^ ^ | = note: `#[warn(unused_parens)]` on by default help: remove these parentheses | 16 - let x_percent = (img_x as f64 / width as f64); 16 + let x_percent = img_x as f64 / width as f64; |
パターンマッチング部分も範囲に重複がある警告がでました。
warning: multiple patterns overlap on their endpoints --> src\main.rs:47:17 | 46 | 3..=5 => '.', | ----- this range overlaps on `5_usize`... 47 | 5..=10 => ':', | ^^^^^^ ... with this range | = note: `#[warn(overlapping_range_endpoints)]` on by default = note: you likely meant to write mutually exclusive ranges
rustのバージョンの違いでしょうか?ただの宗派の違いでしょうか?謎です。
引数
最後の80, 24
は描画サイズのようです。
それ以外はさっぱりわかりません。
マンデルブロ集合 - Wikipediaをみると、なるほど
z = z * z + c;
と対応してそうな式が書いてあります。 各引数がどういう役割なのかは、やはり、よくわかりません。
パラメータをかえたら部分が拡大されて「フラクタルだ!」みたいな体験を期待していたのですが、そういうものではなさそうです。 書いたプログラムの楽しさがわかりません。 今のところ使える道具が限られているせいだと思って、先に進みます。