Vector3D/Point3D
相変わらず作りたいものはないのだけれど、少し前に "The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer" という本を買った。
The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer (Pragmatic Bookshelf)
- 作者: Jamis Buck
- 出版社/メーカー: Pragmatic Bookshelf
- 発売日: 2019/03/08
- メディア: ペーパーバック
- この商品を含むブログを見る
この本はテストケースのみを提示して、特定の言語を対象とせずにシンプルな Raytracer を実装することを目的としている。Rust を使ってこの本を読んでいけば良い経験になる... といいなあ。
とにかくやってみよう。
リポジトリはここ github.com
Tuples, Points, and Vectors
Chapter1 は Point と Vector の実装。本では Point と Vector を tuple を使った 4 つ組みで表現しているが、x, y, z の添字でアクセスしたいこと、Point と Vector の区別ができるなら w 成分は不要なことから、struct で表現する。
各成分には float として f32 を用いる。使用者が f32 と f64 の好きな方を使えるようにしたいけれど、あまり良い方法が思いつかない。
type Float = f32;
とでもしておいた方が良かったか。
浮動小数点関連は誤差はつきもののため、誤差を考慮した比較用関数も用意しておく。
const EPSILON: f32 = 0.0001; fn approx_eq(a: f32, b: f32) -> bool { (a - b).abs() < EPSILON }
また、Vector という名前にすると Vec と間違えそうなので、それぞれ Point3D, Vector3D という名前にした。
Point3D
struct の定義は非常に簡単。
#[derive(Debug, Clone)] pub struct Point3D { pub x: f32, pub y: f32, pub z: f32, }
x, y, z の各メンバに直接アクセスしたいので、pub を付けて公開している。
Vector3D
基本的には Point3D と変わらない。
#[derive(Debug, Clone)] pub struct Vector3D { pub x: f32, pub y: f32, pub z: f32, }
こちらも x, y, z の各メンバに直接アクセスしたいので、pub を付けて公開している。
Operation
Point3D と Vector3D に関する演算を定義する。実装自体に難しいところはないから、ソースを見るだけで何をしているのか分かるはず。