ruby_math/geometry/
ray.rs1#![allow(dead_code)]
2
3use std::fmt::Display;
4
5use crate::algebra::{Mat4d, Transform, Transformable, Vec3d};
6
7#[derive(Clone, Copy, PartialEq, Debug)]
8pub struct Ray {
9 origin: Vec3d,
10 direction: Vec3d,
11}
12
13pub fn ray(origin: Vec3d, direction: Vec3d) -> Ray {
14 Ray::new(origin, direction)
15}
16
17impl Display for Ray {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 write!(
20 f,
21 "Ray(origin: ({}, {}, {}), direction: ({}, {}, {}))",
22 self.origin.x(),
23 self.origin.y(),
24 self.origin.z(),
25 self.direction.x(),
26 self.direction.y(),
27 self.direction.z()
28 )
29 }
30}
31
32impl Default for Ray {
33 fn default() -> Self {
34 Self {
35 origin: Vec3d::default(),
36 direction: Vec3d::default(),
37 }
38 }
39}
40
41impl Ray {
42 pub fn new(origin: Vec3d, direction: Vec3d) -> Self {
43 let direction = direction.normalize();
44 Self { origin, direction }
45 }
46
47 pub fn at(&self, t: f64) -> Vec3d {
48 self.origin + t * self.direction
49 }
50}
51
52impl Ray {
53 pub fn origin(&self) -> Vec3d {
54 self.origin
55 }
56
57 pub fn set_origin(mut self, origin: Vec3d) -> Self {
58 self.origin = origin;
59 self
60 }
61
62 pub fn direction(&self) -> Vec3d {
63 self.direction
64 }
65
66 pub fn set_direction(mut self, direction: Vec3d) -> Self {
67 self.direction = direction;
68 self
69 }
70}
71
72impl Transformable for Ray {
73 fn apply(&self, transform: Transform) -> Self {
74 let origin = transform.transform_point3d(self.origin);
75 let direction = transform.transform_vector3d(self.direction);
76 Self::new(origin, direction)
77 }
78
79 fn apply_matrix4d(&self, matrix: Mat4d) -> Self {
80 let t = Transform::from_matrix4d(matrix);
81 let origin = t.transform_point3d(self.origin);
82 let direction = t.transform_vector3d(self.direction);
83 Self::new(origin, direction)
84 }
85}