diff --git a/rtchallenge/Cargo.lock b/rtchallenge/Cargo.lock index 1ed1b63..c47050a 100644 --- a/rtchallenge/Cargo.lock +++ b/rtchallenge/Cargo.lock @@ -1,5 +1,32 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "float-cmp" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1267f4ac4f343772758f7b1bdcbe767c218bbab93bb432acbf5162bbf85a6c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + [[package]] name = "rtchallenge" version = "0.1.0" +dependencies = [ + "float-cmp", +] diff --git a/rtchallenge/Cargo.toml b/rtchallenge/Cargo.toml index e040b18..5fb80a0 100644 --- a/rtchallenge/Cargo.toml +++ b/rtchallenge/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +float-cmp = "0.8.0" diff --git a/rtchallenge/src/tuples.rs b/rtchallenge/src/tuples.rs index 2a68103..2ad9788 100644 --- a/rtchallenge/src/tuples.rs +++ b/rtchallenge/src/tuples.rs @@ -15,6 +15,19 @@ impl Tuple { fn is_vector(&self) -> bool { self.w == 0.0 } + + fn magnitude(&self) -> f32 { + (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt() + } + fn normalize(&self) -> Tuple { + let m = self.magnitude(); + Tuple { + x: self.x / m, + y: self.y / m, + z: self.z / m, + w: self.w / m, + } + } } impl Add for Tuple { @@ -102,6 +115,8 @@ fn tuple(x: f32, y: f32, z: f32, w: f32) -> Tuple { #[cfg(test)] mod tests { + use float_cmp::approx_eq; + use super::{point, tuple, vector}; #[test] fn is_point() { @@ -185,4 +200,29 @@ mod tests { let a = tuple(1., -2., 3., -4.); assert_eq!(a / 2., tuple(0.5, -1., 1.5, -2.)); } + #[test] + fn vector_magnitude() { + assert_eq!(1., vector(1., 0., 0.).magnitude()); + assert_eq!(1., vector(0., 1., 0.).magnitude()); + assert_eq!(1., vector(0., 0., 1.).magnitude()); + assert_eq!(14_f32.sqrt(), vector(1., 2., 3.).magnitude()); + assert_eq!(14_f32.sqrt(), vector(-1., -2., -3.).magnitude()); + } + #[test] + fn vector_normalize() { + assert_eq!(vector(1., 0., 0.), vector(4., 0., 0.).normalize()); + assert_eq!( + vector(1. / 14_f32.sqrt(), 2. / 14_f32.sqrt(), 3. / 14_f32.sqrt()), + vector(1., 2., 3.).normalize() + ); + } + #[test] + fn vector_normalize_magnitude() { + assert!(approx_eq!( + f32, + 1., + vector(1., 2., 3.).normalize().magnitude(), + ulps = 1 + )); + } }