use std::ops::Rem;
use crate::{F32Fmt, One, SignOps, Two, Zero};
use {
super::Vector,
crate::Construct,
std::{
fmt,
ops::{Add, Div, Sub, Mul, Neg}
}
};
#[derive(PartialEq, Clone, Copy)]
pub struct Vector3<T>(pub T, pub T, pub T);
impl<T> fmt::Debug for Vector3<T>
where T: fmt::Debug + Copy {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({:?}, {:?}, {:?})", self.0, self.1, self.2)
}
}
impl<T> Vector3<T> {
pub fn new(x: T, y: T, z: T) -> Self
where T: Construct<T> {
Vector3(x, y, z)
}
pub fn normalize(&self, length: Option<T>) -> Vector3<T>
where T: Mul<T, Output = T> + Div<T, Output = T> + Add<T, Output = T> + F32Fmt + Copy {
let s = self.norm();
match length {
Some(len) => Vector3(self.0 / s * len, self.1 / s * len, self.2 / s * len),
None => Vector3(self.0 / s, self.1 / s, self.2 / s),
}
}
#[inline]
pub fn norm(&self) -> T
where T: Add<T, Output = T> + Mul<T, Output = T> + F32Fmt + Copy {
(self.0 * self.0 + self.1 * self.1 + self.2 * self.2).sqrt()
}
#[inline]
pub fn unit_vector(&self) -> Self
where Self: Div<T, Output = Self>, T: Add<T, Output = T> + Mul<T, Output = T> + F32Fmt + Copy {
*self / self.norm()
}
pub fn cross_product(a: Self, b: Self) -> Self
where T: Mul<T, Output = T> + Sub<T, Output = T> + Copy {
Vector3(
(a.1 * b.2) - (a.2 * b.1),
(a.2 * b.0) - (a.0 * b.2),
(a.0 * b.1) - (a.1 * b.0)
)
}
pub fn dot_product(a: Self, b: Self) -> T
where T: Mul<T, Output = T> + Add<T, Output = T> + Copy {
(a.0 * b.0) + (a.1 * b.1) + (a.2 * b.2)
}
}
impl<T> Construct<T> for Vector3<T> where T: Construct<T> {}
impl<T> Vector<T> for Vector3<T> where T: Construct<T> {}
impl<T> Add for Vector3<T>
where T: Add<T, Output = T> + Copy {
type Output = Self;
fn add (self, rhs: Self) -> Self::Output{
Vector3(self.0 + rhs.0, self.1 + rhs.1, self.2 + rhs.2)
}
}
impl<T> Add<T> for Vector3<T>
where T: Add<T, Output = T> + Copy {
type Output = Self;
fn add (self, rhs: T) -> Self::Output{
Vector3(self.0 + rhs, self.1 + rhs, self.2 + rhs)
}
}
impl<T> Sub for Vector3<T>
where T: Sub<T, Output = T> + Copy {
type Output = Self;
fn sub (self, rhs: Self) -> Self::Output{
Vector3(self.0 - rhs.0, self.1 - rhs.1, self.2 - rhs.2)
}
}
impl<T> Sub<T> for Vector3<T>
where T: Sub<T, Output = T> + Copy {
type Output = Self;
fn sub (self, rhs: T) -> Self::Output{
Vector3(self.0 - rhs, self.1 - rhs, self.2 - rhs)
}
}
impl<T> Mul for Vector3<T>
where T: Mul<T, Output = T> + Copy {
type Output = Self;
fn mul (self, rhs: Self) -> Self::Output{
Vector3(self.0 * rhs.0, self.1 * rhs.1, self.2 * rhs.2)
}
}
impl<T> Mul<T> for Vector3<T>
where T: Mul<T, Output = T> + Copy {
type Output = Self;
fn mul (self, rhs: T) -> Self::Output{
Vector3(self.0 * rhs, self.1 * rhs, self.2 * rhs)
}
}
impl<T> Div for Vector3<T>
where T: Div<T, Output = T> + Copy {
type Output = Self;
fn div (self, rhs: Self) -> Self::Output{
Vector3(self.0 / rhs.0, self.1 / rhs.1, self.2 / rhs.2)
}
}
impl<T> Div<T> for Vector3<T>
where T: Div<T, Output = T> + Copy {
type Output = Self;
fn div (self, rhs: T) -> Self::Output {
Vector3(self.0 / rhs, self.1 / rhs, self.2 / rhs)
}
}
impl<T> Rem for Vector3<T>
where T: Rem<T, Output = T> + Copy {
type Output = Self;
fn rem (self, rhs: Self) -> Self::Output {
Vector3(self.0 % rhs.0, self.1 % rhs.1, self.2 % rhs.2)
}
}
impl<T> Rem<T> for Vector3<T>
where T: Rem<T, Output = T> + Copy {
type Output = Self;
fn rem (self, rhs: T) -> Self::Output {
Vector3(self.0 % rhs, self.1 % rhs, self.2 % rhs)
}
}
impl<T> Neg for Vector3<T>
where T: Neg<Output = T> + Copy {
type Output = Self;
fn neg(self) -> Self::Output {
Vector3(-self.0, -self.1, -self.2)
}
}
impl<T> Zero for Vector3<T> where T: Zero { const ZERO: Self = Vector3(T::ZERO, T::ZERO, T::ZERO); }
impl<T> One for Vector3<T> where T: One { const ONE: Self = Vector3(T::ONE, T::ONE, T::ONE); }
impl<T> Two for Vector3<T> where T: Two { const TWO: Self = Vector3(T::TWO, T::TWO, T::TWO); }
impl<T> From<Vector3<T>> for [T; 3]
where T: Copy {
fn from(other: Vector3<T>) -> [T; 3]{
[other.0, other.1, other.2]
}
}
impl<T> From<[T; 3]> for Vector3<T>
where T: Copy{
fn from(other: [T; 3]) -> Self {
Vector3(other[0], other[1], other[2])
}
}
impl<T> F32Fmt for Vector3<T>
where T: F32Fmt + Copy {
type F32Fmt = Vector3<T::F32Fmt>;
#[inline]
fn intoF32Fmt(self) -> Self::F32Fmt {
Vector3(self.0.intoF32Fmt(), self.1.intoF32Fmt(), self.2.intoF32Fmt())
}
#[inline]
fn fromF32Fmt(f32_fmt: Self::F32Fmt) -> Self {
let vec = &f32_fmt;
Vector3(T::fromF32Fmt(vec.0), T::fromF32Fmt(vec.1), T::fromF32Fmt(f32_fmt.2))
}
fn sqrt(self) -> Self {
Vector3(self.0.sqrt(), self.1.sqrt(), self.2.sqrt())
}
fn cbrt(self) -> Self {
Vector3(self.0.cbrt(), self.1.cbrt(), self.2.cbrt())
}
fn f32_const_mul(self, constant: f32) -> Self {
Vector3(self.0.f32_const_mul(constant), self.1.f32_const_mul(constant), self.2.f32_const_mul(constant))
}
fn sin_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn cos_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn tan_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn asin_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn acos_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn atan_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn atan2_mul(self, _other: Self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn sinh_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn cosh_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
fn tanh_mul(self, _mul_by: Self) -> Self where Self: Mul<Self, Output = Self> + Sized {
todo!()
}
}
impl<T> SignOps for Vector3<T> {
fn ptcopysign(self, _sign: Self) -> Self {
todo!()
}
fn ptsignum(self) -> i8 {
todo!()
}
fn abs(self) -> Self {
todo!()
}
}