Add magnitude() and normalize() methods to Tuple

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

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