1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use crate::float::Float; use crate::vector::Vec3; #[derive(Debug)] pub struct Ray<T> where T: Float { origin: Vec3<T>, direction: Vec3<T> } impl<T> Ray<T> where T: Float { pub fn new() -> Self { let origin = [T::zero(); 3]; let direction = [T::zero(); 3]; Ray { origin: Vec3::from_array(origin), direction: Vec3::from_array(direction), } } pub fn from_vec(origin: Vec3<T>, direction: Vec3<T>) -> Self { Ray { origin, direction } } pub fn from_array(origin: [T; 3], direction: [T; 3]) -> Self { Ray { origin: Vec3::from_array(origin), direction: Vec3::from_array(direction), } } pub fn from_slice(origin: &[T], direction: &[T]) -> Self { Ray { origin: Vec3::from_slice(origin), direction: Vec3::from_slice(direction), } } pub fn from_ray(ray: &Ray<T>) -> Self { Ray { origin: Vec3::from_slice(ray.get_origin().get_data()), direction: Vec3::from_slice(ray.get_direction().get_data()) } } pub fn get_origin(&self) -> &Vec3<T> { &self.origin } pub fn get_direction(&self) -> &Vec3<T> { &self.direction } pub fn get_point(&self, t: T) -> Vec3<T> { &self.origin + &self.direction * t } } #[cfg(test)] mod tests { use super::*; #[test] fn init() { let ray = Ray::<f64>::new(); assert_eq!(ray.get_origin().get_data(), [0.0, 0.0, 0.0]); assert_eq!(ray.get_direction().get_data(), [0.0, 0.0, 0.0]); let origin = Vec3::<f64>::from_array([0.0, -1.0, -2.0]); let direction = Vec3::<f64>::from_array([0.0, 0.0, 1.0]); let ray = Ray::from_vec(origin, direction); assert_eq!(ray.get_origin().get_data(), [0.0, -1.0, -2.0]); assert_eq!(ray.get_direction().get_data(), [0.0, 0.0, 1.0]); let origin = [0.0, 1.0, 2.0]; let direction = [0.0, 0.0, -1.0]; let ray = Ray::from_array(origin, direction); assert_eq!(ray.get_origin().get_data(), [0.0, 1.0, 2.0]); assert_eq!(ray.get_direction().get_data(), [0.0, 0.0, -1.0]); let origin = vec!(-1.0, 1.0, 2.0); let direction = vec!(-1.0, 0.0, -1.0); let ray = Ray::<f64>::from_slice(&origin, &direction); assert_eq!(ray.get_origin().get_data(), [-1.0, 1.0, 2.0]); assert_eq!(ray.get_direction().get_data(), [-1.0, 0.0, -1.0]); } #[test] fn point() { let origin = [0.0, 1.0, 2.0]; let direction = [1.0, 2.0, 3.0]; let ray = Ray::from_array(origin, direction); let t = -1.5; let p = ray.get_point(t); assert_eq!(p.get_data(), [-1.5, -2.0, -2.5]); } }