Add magnitude() and normalize() methods to Tuple

This commit is contained in:
Bill Thiede 2021-06-24 15:07:38 -07:00
parent 758f94acde
commit 1ea90770bc
3 changed files with 68 additions and 0 deletions

27
rtchallenge/Cargo.lock generated
View File

@ -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",
]

View File

@ -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"

View File

@ -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
));
}
}