use core::ops::{Neg, Mul, MulAssign, Div, DivAssign};
use crate::Ray3;
use crate::Vector2;
use crate::{MulDivScalar, impl_mul, impl_div};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, Copy)]
pub struct Ray2 {
origin: Vector2,
direction: Vector2,
}
impl Ray2 {
pub fn new(origin: Vector2, direction: Vector2) -> Self { Ray2 { origin, direction } }
}
impl Ray2 {
pub fn origin(&self) -> Vector2 { self.origin }
pub fn set_origin(&mut self, value: Vector2) { self.origin = value; }
pub fn direction(&self) -> Vector2 { self.direction }
pub fn set_direction(&mut self, value: Vector2) { self.direction = value; }
}
impl Ray2 {
pub fn get_point(self, distance: f32) -> Vector2 {
let dir = self.direction * distance;
return self.origin + dir;
}
pub fn closest_point(self, point: Vector2) -> Vector2 {
let diff = point - self.origin;
let projected = diff.project(self.direction);
return projected + self.origin;
}
pub fn distance(self, point: Vector2) -> f32 { point.distance(self.closest_point(point)) }
}
impl From<Ray3> for Ray2 {
fn from(value: Ray3) -> Self {
Ray2::new(value.origin().to_vector2(), value.direction().to_vector2())
}
}
unsafe impl Send for Ray2 {}
unsafe impl Sync for Ray2 {}
impl Eq for Ray2 {}
impl PartialEq for Ray2 {
fn eq(&self, other: &Self) -> bool {
self.origin == other.origin
&& self.direction == other.direction
}
}
#[cfg(not(feature = "no_std"))]
impl std::fmt::Display for Ray2 {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&format!("{{ origin: {}, direction: {} }}", self.origin, self.direction))
}
}
impl MulDivScalar for Ray2 {
type Output = Ray2;
fn multiply_scalar(self, rhs: f32) -> Self::Output {
Ray2::new(self.origin, rhs * self.direction)
}
fn multiply_assign_scalar(&mut self, rhs: f32) {
self.direction *= rhs;
}
fn divide_scalar(self, rhs: f32) -> Self::Output {
Ray2::new(self.origin, self.direction / rhs)
}
fn divide_assign_scalar(&mut self, rhs: f32) {
self.direction /= rhs;
}
fn reciprocal_scalar(self, rhs: f32) -> Self::Output {
Ray2::new(self.origin, rhs / self.direction)
}
}
impl Neg for Ray2 {
type Output = Ray2;
fn neg(self) -> Self::Output { Ray2::new(self.origin, -self.direction) }
}
impl_mul!(Ray2);
impl_div!(Ray2);