Drawing on a Canvas
Chapter2
The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer (Pragmatic Bookshelf)
- 作者: Jamis Buck
- 出版社/メーカー: Pragmatic Bookshelf
- 発売日: 2019/03/08
- メディア: ペーパーバック
- この商品を含むブログを見る
Color
基本的には Point3D や Vector3D と変わらない。x, y, z の代わりに red, green, blue になっている。
pub struct Color { pub red: f32, pub green: f32, pub blue: f32, }
また、Point3D や Vector3D と違い、Color 同士の演算しかないため、こちらの方が簡単かも。
Canvas
内部的には単純な Color の配列として実装する。
pub struct Canvas { width: usize, height: usize, colors: Vec<Color>, }
これで width x height の Canvas を表現する。(x, y) の Color には width * y + x でアクセスする。また、Canvas の原点は左上。
PPM への出力
PPM は以前にも扱ったことがあるけれど、その時はバイナリ形式だった。
一方で今回はテキスト形式。また、Color は各成分が f32 であるため、出力時には [0.0, 1.0] を u8 の [0, 255] に変換しなくてはならない。
let c = self.color_at(j, i); let r = (c.red * 255.0).round().min(255.0).max(0.0) as u8; let g = (c.green * 255.0).round().min(255.0).max(0.0) as u8; let b = (c.blue * 255.0).round().min(255.0).max(0.0) as u8;
そして、本では PPM の制限として 1 行 70 カラムまでというのを強調しており、わざわざ 70 カラムを越えないことを確認するテストケースまで用意していた。この点に関しては毎行 1 pixel にすれば気にせずに済むため、そのようにしている。
というか、一行が 70 カラムを越えない範囲でなるべく多くの情報を詰め込もうとした結果、行あたりの pixel 数が変わってしまったり、同じ pixel の red, green, blue の途中で改行したりといったことが起こり得る。それではせっかくテキストで出力しているのに、分かりにくくなってしまうのではなかろうか。