use core::{
fmt,
ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign},
};
use super::{Magnitude, V3};
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Default, PartialEq)]
pub struct Direction {
v: V3,
}
pub type Position = Direction;
impl Direction {
pub fn new(x: Magnitude, y: Magnitude, z: Magnitude) -> Self {
Self {
v: V3::new(x, y, z),
}
}
pub fn to_array(&self) -> [Magnitude; 3] {
self.v.to_array()
}
pub fn x(&self) -> Magnitude {
self.v.to_array()[0]
}
pub fn y(&self) -> Magnitude {
self.v.to_array()[1]
}
pub fn z(&self) -> Magnitude {
self.v.to_array()[2]
}
#[inline]
pub fn magnitude(&self) -> Magnitude {
self.v.length()
}
pub fn magnitude_squared(&self) -> Magnitude {
self.v.length_squared()
}
pub fn normalize(&self) -> Direction {
Self {
v: self.v.normalize(),
}
}
pub fn cross(&self, other: Self) -> Self {
Self {
v: self.v.cross(other.v),
}
}
pub fn dot(&self, other: Self) -> Magnitude {
self.v.dot(other.v)
}
pub fn vector(&self) -> V3 {
self.v
}
}
impl Direction {
pub const ZERO: Self = Self { v: V3::ZERO };
pub const ONE: Self = Self { v: V3::ONE };
}
impl Add for Direction {
type Output = Self;
fn add(self, other: Self) -> Self {
Self {
v: self.v + other.v,
}
}
}
impl AddAssign for Direction {
fn add_assign(&mut self, other: Self) {
*self = Self {
v: self.v + other.v,
};
}
}
impl Sub for Direction {
type Output = Self;
fn sub(self, other: Self) -> Self {
Self {
v: self.v - other.v,
}
}
}
impl SubAssign for Direction {
fn sub_assign(&mut self, other: Self) {
*self = Self {
v: self.v - other.v,
};
}
}
impl Mul<Magnitude> for Direction {
type Output = Self;
fn mul(self, other: Magnitude) -> Self {
Self { v: self.v * other }
}
}
impl MulAssign<Magnitude> for Direction {
fn mul_assign(&mut self, other: Magnitude) {
*self = Self { v: self.v * other };
}
}
impl Div<Magnitude> for Direction {
type Output = Self;
fn div(self, other: Magnitude) -> Self {
Self { v: self.v / other }
}
}
impl DivAssign<Magnitude> for Direction {
fn div_assign(&mut self, other: Magnitude) {
*self = Self { v: self.v / other };
}
}
impl fmt::Display for Direction {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.v)
}
}