#![allow(dead_code)] use num_traits::{Num, PrimInt, Signed, Zero}; use std::fmt; use std::ops::{Add, Div, Mul, Neg, Sub}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] pub struct Pos3([T; 3]); impl Pos3 { #[inline] pub const fn new(x: T, y: T, z: T) -> Pos3 { Pos3([x, y, z]) } #[inline] pub fn get_x(&self) -> &T { &self.0[0] } #[inline] pub fn get_y(&self) -> &T { &self.0[1] } #[inline] pub fn get_z(&self) -> &T { &self.0[2] } } impl Pos3 { pub fn is_unit(&self) -> bool { self.abs() == T::one() } } impl From<&[T]> for Pos3 { fn from(value: &[T]) -> Self { match value.len() { 0 => Pos3::new(T::default(), T::default(), T::default()), 1 => Pos3::new(value[0], T::default(), T::default()), 2 => Pos3::new(value[0], value[1], T::default()), _ => Pos3::new(value[0], value[1], value[2]), } } } impl From<[T; 3]> for Pos3 { fn from(value: [T; 3]) -> Self { Pos3(value) } } impl From<(T, T, T)> for Pos3 { fn from(value: (T, T, T)) -> Self { Pos3([value.0, value.1, value.2]) } } impl Pos3 where T: Copy, { #[inline] pub fn splat(v: T) -> Pos3 { Pos3::new(v, v, v) } #[inline] pub fn x(&self) -> T { self.0[0] } #[inline] pub fn y(&self) -> T { self.0[1] } #[inline] pub fn z(&self) -> T { self.0[2] } } impl Zero for Pos3 where T: Num + Zero + Copy, { fn zero() -> Self { Pos3::splat(T::zero()) } fn is_zero(&self) -> bool { self.x().is_zero() && self.y().is_zero() && self.z().is_zero() } } impl Pos3 where T: Signed, { pub fn abs(self) -> T { self.get_x().abs() + self.get_y().abs() + self.get_z().abs() } } impl fmt::Display for Pos3 where T: Num + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "({}, {}, {})", self.get_x(), self.get_y(), self.get_z()) } } impl>> Add

for Pos3 where T: Num + Copy, { type Output = Self; fn add(self, rhs: P) -> Self::Output { let rhs = rhs.into(); Pos3::new(self.x() + rhs.x(), self.y() + rhs.y(), self.z() + rhs.z()) } } impl>> Sub

for Pos3 where T: Num + Copy, { type Output = Pos3; fn sub(self, rhs: P) -> Self::Output { let rhs = rhs.into(); Pos3::new(self.x() - rhs.x(), self.y() - rhs.y(), self.z() - rhs.z()) } } impl Mul for Pos3 where T: Num + Copy, { type Output = Self; fn mul(self, rhs: T) -> Self::Output { Pos3::new(self.x() * rhs, self.y() * rhs, self.z() * rhs) } } impl Div for Pos3 where T: Num + Copy, { type Output = Self; fn div(self, rhs: T) -> Self::Output { Pos3::new(self.x() / rhs, self.y() / rhs, self.z() / rhs) } } impl Neg for Pos3 where T: Signed + Copy, { type Output = Pos3; fn neg(self) -> Self::Output { Pos3::new(-self.x(), -self.y(), -self.z()) } } impl Mul> for Pos3 where T: Num + Copy, { type Output = Pos3; fn mul(self, rhs: Pos3) -> Self::Output { Pos3([ self.y() * rhs.z() - self.z() * rhs.y(), self.z() * rhs.x() - self.x() * rhs.z(), self.x() * rhs.y() - self.y() * rhs.x(), ]) } }