Add primitive math operations

This commit is contained in:
Savanni D'Gerinel 2024-06-09 13:19:47 -04:00
parent 01f3e05235
commit e23a4aacab
1 changed files with 198 additions and 4 deletions

View File

@ -1,10 +1,10 @@
const EPSILON: f64 = 0.00001; const EPSILON: f64 = 0.00001;
fn eq_f64(l: f64, r: f64) -> bool { fn eq_f64(l: f64, r: f64) -> bool {
(l-r).abs() < EPSILON (l - r).abs() < EPSILON
} }
#[derive(Debug)]
struct Tuple { struct Tuple {
x: f64, x: f64,
y: f64, y: f64,
@ -20,11 +20,55 @@ impl PartialEq for Tuple {
} }
} }
impl std::ops::Add for Tuple {
type Output = Tuple;
fn add(self, r: Tuple) -> Self::Output {
return Self::Output {
x: self.x + r.x,
y: self.y + r.y,
z: self.z + r.z,
w: self.w + r.w,
};
}
}
impl std::ops::Sub for Tuple {
type Output = Tuple;
fn sub(self, r: Tuple) -> Self::Output {
return Self::Output {
x: self.x - r.x,
y: self.y - r.y,
z: self.z - r.z,
w: self.w - r.w,
};
}
}
impl std::ops::Neg for Tuple {
type Output = Tuple;
fn neg(self) -> Self::Output {
return Self::Output {
x: -self.x,
y: -self.y,
z: -self.z,
w: -self.w,
};
}
}
#[derive(Debug, PartialEq)]
struct Point(Tuple); struct Point(Tuple);
impl Point { impl Point {
fn new(x: f64, y: f64, z: f64) -> Self { fn new(x: f64, y: f64, z: f64) -> Self {
Self(Tuple{ x, y, z, w: 1.0 }) Self(Tuple { x, y, z, w: 1.0 })
}
}
impl From<Tuple> for Point {
fn from(tuple: Tuple) -> Self {
assert_eq!(tuple.w, 1.0);
Self(tuple)
} }
} }
@ -34,11 +78,42 @@ impl Default for Point {
} }
} }
impl std::ops::Add<Vector> for Point {
type Output = Point;
fn add(self, r: Vector) -> Self::Output {
Point::from(self.0 + r.0)
}
}
impl std::ops::Sub for Point {
type Output = Vector;
fn sub(self, r: Point) -> Self::Output {
Vector::from(self.0 - r.0)
}
}
impl std::ops::Sub<Vector> for Point {
type Output = Point;
fn sub(self, r: Vector) -> Self::Output {
Point::from(self.0 - r.0)
}
}
impl std::ops::Neg for Point {
type Output = Point;
fn neg(self) -> Self::Output {
let mut t = -self.0;
t.w = 1.;
Point::from(t)
}
}
#[derive(Debug, PartialEq)]
struct Vector(Tuple); struct Vector(Tuple);
impl Vector { impl Vector {
fn new(x: f64, y: f64, z: f64) -> Self { fn new(x: f64, y: f64, z: f64) -> Self {
Self(Tuple{ x, y, z, w: 0.0 }) Self(Tuple { x, y, z, w: 0.0 })
} }
} }
@ -48,6 +123,29 @@ impl Default for Vector {
} }
} }
impl From<Tuple> for Vector {
fn from(tuple: Tuple) -> Self {
assert_eq!(tuple.w, 0.0);
Self(tuple)
}
}
impl std::ops::Sub for Vector {
type Output = Vector;
fn sub(self, r: Self) -> Self {
Vector::from(self.0 - r.0)
}
}
impl std::ops::Neg for Vector {
type Output = Vector;
fn neg(self) -> Self::Output {
let mut t = -self.0;
t.w = 0.;
Vector::from(t)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -59,4 +157,100 @@ mod tests {
assert!(eq_f64(0.9999994, 0.9999995)); assert!(eq_f64(0.9999994, 0.9999995));
assert!(!eq_f64(0.9995, 0.9994)); assert!(!eq_f64(0.9995, 0.9994));
} }
#[test]
fn add_two_tuples() {
let a = Tuple {
x: 3.,
y: -2.,
z: 5.,
w: 1.,
};
let b = Tuple {
x: -2.,
y: 3.,
z: 1.,
w: 0.,
};
assert_eq!(
a + b,
Tuple {
x: 1.,
y: 1.,
z: 6.,
w: 1.
}
);
}
#[test]
fn subtracts_two_tuples() {
let a = Tuple {
x: 3.,
y: 2.,
z: 1.,
w: 1.,
};
let b = Tuple {
x: 5.,
y: 6.,
z: 7.,
w: 1.,
};
assert_eq!(
a - b,
Tuple {
x: -2.,
y: -4.,
z: -6.,
w: 0.
}
);
}
#[test]
fn adds_point_and_vector() {
let a = Point::new(3., -2., 5.);
let b = Vector::new(-2., 3., 1.);
assert_eq!(a + b, Point::new(1., 1., 6.,));
}
#[test]
fn subtracts_two_points() {
let a = Point::new(3., 2., 1.);
let b = Point::new(5., 6., 7.);
assert_eq!(a - b, Vector::new(-2., -4., -6.,));
}
#[test]
fn subtracts_vector_from_point() {
let a = Point::new(3., 2., 1.);
let b = Vector::new(5., 6., 7.);
assert_eq!(a - b, Point::new(-2., -4., -6.));
}
#[test]
fn subtracts_two_vectors() {
let a = Vector::new(3., 2., 1.);
let b = Vector::new(5., 6., 7.);
assert_eq!(a - b, Vector::new(-2., -4., -6.));
}
#[test]
fn it_negates_primitives() {
assert_eq!(
-Tuple {
x: 1.,
y: 2.,
z: 3.,
w: 4.
},
Tuple {
x: -1.,
y: -2.,
z: -3.,
w: -4.
},
);
}
} }