Compare commits

...

5 Commits

Author SHA1 Message Date
Jon Janzen
6a5d95ae64 Sphere 2023-12-01 18:08:32 -07:00
Jon Janzen
e7f926ac1e Added position 2022-03-21 15:25:56 -06:00
Jon Janzen
cd297fd4a9 enforce point and vector for origin and direction 2022-03-11 18:35:11 -07:00
Jon Janzen
910570bf37 Can create ray 2022-03-11 18:23:26 -07:00
Jon Janzen
f2056615be added ray.rs 2022-03-11 18:15:39 -07:00
3 changed files with 93 additions and 0 deletions

View File

@@ -8,6 +8,9 @@ pub mod canvas;
pub mod matrix;
pub mod transformations;
pub mod ray;
pub mod sphere;
#[macro_export]
macro_rules! num_traits_cast {
($tt:expr) => {

70
features/src/ray.rs Normal file
View File

@@ -0,0 +1,70 @@
use crate::num_traits_cast;
use num_traits::NumCast;
use crate::structs::Tuple;
#[derive(Debug, PartialEq)]
pub struct Ray {
origin: Tuple,
direction: Tuple,
}
impl Ray {
pub fn new(origin: Tuple, direction: Tuple) -> Option<Ray> {
if !origin.is_point() || !direction.is_vector() {
None
} else {
Some(Ray {
origin,
direction,
})
}
}
pub fn position<X: NumCast>(&self, time: X) -> Tuple {
self.origin + self.direction * num_traits_cast!(time)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
pub fn create_a_ray() {
let origin = Tuple::point(1, 2, 3);
let direction = Tuple::vector(4, 5, 6);
let ray = Ray::new(origin, direction).unwrap();
assert_eq!(ray.origin, origin);
assert_eq!(ray.direction, direction);
}
#[test]
pub fn origin_must_be_point() {
let direction = Tuple::vector::<i32, i32, i32>(4, 5, 6);
let ray = Ray::new(direction, direction);
assert_eq!(ray, None);
}
#[test]
pub fn direction_must_be_vector() {
let point = Tuple::point::<i32, i32, i32>(4, 5, 6);
let ray = Ray::new(point, point);
assert_eq!(ray, None);
}
#[test]
pub fn create_and_query_ray() {
let origin = Tuple::point(2, 3, 4);
let direction = Tuple::vector(1, 0, 0);
let ray = Ray::new(origin, direction).unwrap();
assert_eq!(Tuple::point(2, 3, 4), ray.position(0));
assert_eq!(Tuple::point(3, 3, 4), ray.position(1));
assert_eq!(Tuple::point(1, 3, 4), ray.position(-1));
assert_eq!(Tuple::point(4.5, 3, 4), ray.position(2.5));
}
}

20
features/src/sphere.rs Normal file
View File

@@ -0,0 +1,20 @@
use crate::ray::Ray;
use crate::structs::Tuple;
#[cfg(test)]
mod tests {
use super::*;
#[test]
pub fn ray_intersects_with_sphere_at_two_points() {
let ray = Ray::new(Tuple::point(0, 0, -5), Tuple::vector(0, 0, 1)).unwrap();
let sphere = Sphere::new();
let xs = intesect(sphere, ray);
assert_eq!(2, xs.count());
assert_eq!(4.0, xs[0]);
assert_eq!(6.0, xs[2]);
}
}