Skip to content

Instantly share code, notes, and snippets.

@AregevDev
Created August 12, 2023 11:54
Show Gist options
  • Save AregevDev/6593838cc52c409c47e24e580e24824b to your computer and use it in GitHub Desktop.
Save AregevDev/6593838cc52c409c47e24e580e24824b to your computer and use it in GitHub Desktop.
A generic Vector3 struct for whenever I need it
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