bs-trace 0.3.0

Free RayTracing software
Documentation
use super::prelude::*;
use num_traits::{Float, One};
use std::iter::Sum;
use std::ops::{Add, Mul};

/// A ray with an origin and a direction. The direction is normalised.
pub struct Ray<T, const N: usize> {
    pub origin: Vector<T, N>,
    pub direction: Vector<T, N>,
}

impl<T, const N: usize> Ray<T, N> {
    /// Constructs a ray from an origin and direction. The given direction is normalised by the callee.
    pub fn new(origin: Vector<T, N>, direction: Vector<T, N>) -> Self
    where
        T: Mul<T, Output = T> + Clone + Sum + One + Float,
    {
        let direction_normalised = direction.normalised();
        unsafe { Self::new_unchecked(origin, direction_normalised) }
    }

    /// Constructs a ray from an origin and direction.
    ///
    /// # Safety
    ///
    /// The caller must ensure that the direction vector is normalised.
    pub unsafe fn new_unchecked(origin: Vector<T, N>, direction: Vector<T, N>) -> Self {
        Self { origin, direction }
    }

    /// Evaluates this ray at t.
    ///
    /// In the case of non-negative t, `ray.at(t)` is the point that is t units away from the ray's
    /// origin, in the ray's direction.
    ///
    /// In the case of negative t, `ray.at(t)` is the point that is -t units away from the ray's
    /// origin, in the opposite direction to the ray's direction.
    pub fn at(&self, t: T) -> Vector<T, N>
    where
        T: Add<T, Output = T> + Mul<T, Output = T> + Clone,
    {
        let ds = self.direction.clone() * t;
        self.origin.clone() + ds
    }
}