Pumpkin/pumpkin-world/src/vector3.rs
2024-08-17 20:40:06 +02:00

114 lines
2.3 KiB
Rust

use std::ops::{Add, Div, Mul, Neg, Sub};
use num_traits::Float;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Vector3<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<T: Math + Copy> Vector3<T> {
pub fn new(x: T, y: T, z: T) -> Self {
Vector3 { x, y, z }
}
pub fn length_sqared(&self) -> T {
self.x * self.x + self.y * self.y + self.z * self.z
}
pub fn add(&self, other: &Vector3<T>) -> Self {
Vector3 {
x: self.x + other.x,
y: self.y + other.y,
z: self.z + other.z,
}
}
pub fn sub(&self, other: &Vector3<T>) -> Self {
Vector3 {
x: self.x - other.x,
y: self.y - other.y,
z: self.z - other.z,
}
}
pub fn multiply(self, x: T, y: T, z: T) -> Self {
Self {
x: self.x * x,
y: self.y * y,
z: self.z * z,
}
}
}
impl<T: Math + Copy + Float> Vector3<T> {
pub fn length(&self) -> T {
self.length_sqared().sqrt()
}
pub fn normalize(&self) -> Self {
let length = self.length();
Vector3 {
x: self.x / length,
y: self.y / length,
z: self.z / length,
}
}
}
impl<T: Math + Copy> Mul<T> for Vector3<T> {
type Output = Self;
fn mul(self, scalar: T) -> Self {
Self {
x: self.x * scalar,
y: self.y * scalar,
z: self.z * scalar,
}
}
}
impl<T: Math + Copy> Add for Vector3<T> {
type Output = Vector3<T>;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
}
}
}
impl<T: Math + Copy> Neg for Vector3<T> {
type Output = Self;
fn neg(self) -> Self {
Vector3 {
x: -self.x,
y: -self.y,
z: -self.z,
}
}
}
impl<T> From<(T, T, T)> for Vector3<T> {
fn from((x, y, z): (T, T, T)) -> Self {
Vector3 { x, y, z }
}
}
pub trait Math:
Mul<Output = Self>
+ Neg<Output = Self>
+ Add<Output = Self>
+ Div<Output = Self>
+ Sub<Output = Self>
+ Sized
{
}
impl Math for f64 {}
impl Math for f32 {}
impl Math for i32 {}
impl Math for i64 {}