Created
August 12, 2023 11:54
-
-
Save AregevDev/6593838cc52c409c47e24e580e24824b to your computer and use it in GitHub Desktop.
A generic Vector3 struct for whenever I need it
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; | |
use num_traits::{Float, Num, NumAssignOps}; | |
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)] | |
pub struct Vector3<T: Num + Copy> { | |
pub x: T, | |
pub y: T, | |
pub z: T, | |
} | |
pub type Vector3f = Vector3<f32>; | |
pub type Vector3i = Vector3<i32>; | |
impl<T: Num + Copy> Vector3<T> { | |
pub fn new(x: T, y: T, z: T) -> Self { | |
Vector3 { x, y, z } | |
} | |
pub fn dot(&self, other: Vector3<T>) -> T { | |
self.x * other.x + self.y * other.y + self.z * other.z | |
} | |
pub fn cross(&self, other: Vector3<T>) -> Self { | |
Vector3::from([ | |
self.y * other.z - self.z * other.y, | |
self.z * other.x - self.x * other.z, | |
self.x * other.y - self.y * other.x, | |
]) | |
} | |
} | |
impl<T: Float> Vector3<T> { | |
fn length_squared(&self) -> T { | |
self.dot(*self) | |
} | |
fn length(&self) -> T { | |
self.length_squared().sqrt() | |
} | |
fn normalize(&self) -> Self { | |
*self / self.length() | |
} | |
} | |
impl<T: Num + Copy> From<[T; 3]> for Vector3<T> { | |
fn from(arr: [T; 3]) -> Vector3<T> { | |
Vector3 { x: arr[0], y: arr[1], z: arr[2] } | |
} | |
} | |
impl<T: Num + Copy> Add for Vector3<T> { | |
type Output = Vector3<T>; | |
fn add(self, rhs: Vector3<T>) -> Self::Output { | |
Vector3::from([ | |
self.x + rhs.x, | |
self.y + rhs.y, | |
self.z + rhs.z, | |
]) | |
} | |
} | |
impl<T: Num + NumAssignOps + Copy> AddAssign for Vector3<T> { | |
fn add_assign(&mut self, rhs: Self) { | |
self.x += rhs.x; | |
self.y += rhs.y; | |
self.z += rhs.z; | |
} | |
} | |
impl<T: Num + Copy> Sub for Vector3<T> { | |
type Output = Vector3<T>; | |
fn sub(self, rhs: Vector3<T>) -> Self::Output { | |
Vector3::from([ | |
self.x - rhs.x, | |
self.y - rhs.y, | |
self.z - rhs.z, | |
]) | |
} | |
} | |
impl<T: Num + NumAssignOps + Copy> SubAssign for Vector3<T> { | |
fn sub_assign(&mut self, rhs: Self) { | |
self.x -= rhs.x; | |
self.y -= rhs.y; | |
self.z -= rhs.z; | |
} | |
} | |
impl<T: Num + Copy> Mul for Vector3<T> { | |
type Output = Vector3<T>; | |
fn mul(self, rhs: Vector3<T>) -> Self::Output { | |
Vector3::from([ | |
self.x * rhs.x, | |
self.y * rhs.y, | |
self.z * rhs.z, | |
]) | |
} | |
} | |
impl<T: Num + Copy> Mul<T> for Vector3<T> { | |
type Output = Vector3<T>; | |
fn mul(self, rhs: T) -> Self::Output { | |
Vector3::from([ | |
self.x * rhs, | |
self.y * rhs, | |
self.z * rhs, | |
]) | |
} | |
} | |
impl<T: Num + NumAssignOps + Copy> MulAssign for Vector3<T> { | |
fn mul_assign(&mut self, rhs: Self) { | |
self.x *= rhs.x; | |
self.y *= rhs.y; | |
self.z *= rhs.z; | |
} | |
} | |
impl<T: Num + NumAssignOps + Copy> MulAssign<T> for Vector3<T> { | |
fn mul_assign(&mut self, rhs: T) { | |
self.x *= rhs; | |
self.y *= rhs; | |
self.z *= rhs; | |
} | |
} | |
impl<T: Num + Copy> Div for Vector3<T> { | |
type Output = Vector3<T>; | |
fn div(self, rhs: Vector3<T>) -> Self::Output { | |
Vector3::from([ | |
self.x / rhs.x, | |
self.y / rhs.y, | |
self.z / rhs.z, | |
]) | |
} | |
} | |
impl<T: Num + Copy> Div<T> for Vector3<T> { | |
type Output = Vector3<T>; | |
fn div(self, rhs: T) -> Self::Output { | |
Vector3::from([ | |
self.x / rhs, | |
self.y / rhs, | |
self.z / rhs, | |
]) | |
} | |
} | |
impl<T: Num + NumAssignOps + Copy> DivAssign for Vector3<T> { | |
fn div_assign(&mut self, rhs: Self) { | |
self.x /= rhs.x; | |
self.y /= rhs.y; | |
self.z /= rhs.z; | |
} | |
} | |
impl<T: Num + NumAssignOps + Copy> DivAssign<T> for Vector3<T> { | |
fn div_assign(&mut self, rhs: T) { | |
self.x /= rhs; | |
self.y /= rhs; | |
self.z /= rhs; | |
} | |
} | |
impl<T: Num + Neg<Output = T> + Copy> Neg for Vector3<T> { | |
type Output = Vector3<T>; | |
fn neg(self) -> Self::Output { | |
Vector3::from([ | |
-self.x, | |
-self.y, | |
-self.z, | |
]) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment