use super::CoordSystem::*;
use super::*;
use rand::Rng;
use std::ops::{Add, Div, Mul, Range, Sub, AddAssign, SubAssign, MulAssign, DivAssign, Rem, RemAssign};
#[derive(Copy, Clone, Debug)]
pub struct Vec2 {
pub x: f32,
pub y: f32,
coord_system: CoordSystem,
}
impl Default for Vec2 {
fn default() -> Self {
Self {
x: 0.0,
y: 0.0,
coord_system: CARTESIAN,
}
}
}
impl Add for Vec2 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
coord_system: self.coord_system,
}
}
}
impl AddAssign for Vec2 {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl Sub for Vec2 {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
coord_system: self.coord_system,
}
}
}
impl SubAssign for Vec2 {
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
impl Mul for Vec2 {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self {
x: self.x * rhs.x,
y: self.y * rhs.y,
coord_system: self.coord_system,
}
}
}
impl MulAssign for Vec2 {
fn mul_assign(&mut self, rhs: Self) {
*self = *self * rhs;
}
}
impl Div for Vec2 {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self {
x: self.x / rhs.x,
y: self.y / rhs.y,
coord_system: self.coord_system,
}
}
}
impl DivAssign for Vec2 {
fn div_assign(&mut self, rhs: Self) {
*self = *self / rhs;
}
}
impl Rem for Vec2 {
type Output = Self;
fn rem(self, rhs: Self) -> Self::Output {
Vec2{
x: self.x % rhs.x,
y: self.y % rhs.y,
coord_system: CARTESIAN,
}
}
}
impl RemAssign for Vec2 {
fn rem_assign(&mut self, rhs: Self) {
*self = *self % rhs;
}
}
impl PartialEq for Vec2 {
fn eq(&self, rhs: &Self) -> bool {
if (*self - *rhs).x.abs() < 0.00001
&& (*self - *rhs).y.abs() < 0.00001
&& self.coord_system == rhs.coord_system
{
true
} else {
false
}
}
fn ne(&self, rhs: &Self) -> bool {
if (*self - *rhs).x.abs() > 0.00001 && (*self - *rhs).y.abs() > 0.00001 {
true
} else {
false
}
}
}
impl Vec2 {
pub fn new(x: &f32, y: &f32) -> Vec2 {
let temp = Vec2 {
x: *x,
y: *y,
coord_system: CARTESIAN,
};
temp
}
pub fn create_random(range_x: &Range<f32>) -> Vec2 {
let temp = Vec2 {
x: rand::thread_rng().gen_range(range_x.clone()),
y: rand::thread_rng().gen_range(range_x.clone()),
coord_system: CARTESIAN,
};
temp
}
pub fn create_random2(range_x: &Range<f32>, range_y: &Range<f32>) -> Vec2 {
let temp = Vec2 {
x: rand::thread_rng().gen_range(range_x.clone()),
y: rand::thread_rng().gen_range(range_y.clone()),
coord_system: CARTESIAN,
};
temp
}
pub fn from_angle(theta: &f32, in_mag: &Option<f32>) -> Vec2 {
if let Some(mag) = in_mag {
let mut temp = Vec2 {
x: *mag,
y: *theta,
coord_system: POLAR,
};
temp.swap_system(CARTESIAN);
temp
} else {
let mut temp = Vec2 {
x: 1.0,
y: *theta,
coord_system: POLAR,
};
temp.swap_system(CARTESIAN);
temp
}
}
pub fn from_rand_angle(range_x: &Range<f32>, mag: &Option<f32>) -> Vec2 {
let temp = Vec2::from_angle(&rand::thread_rng().gen_range(range_x.clone()), mag);
temp
}
pub fn random_unit(range: &Range<f32>) -> Vec2 {
let temp = Vec2::from_angle(&rand::thread_rng().gen_range(range.clone()), &None);
temp
}
pub fn unit() -> Vec2 {
let temp = Vec2::from_angle(&0.0, &Some(1.0));
temp
}
pub fn add(&mut self, rhs: &Vec2) {
self.swap_system(CARTESIAN);
self.x += rhs.x;
self.y += rhs.y;
}
pub fn angle_between(&self, rhs: &Vec2) -> f32 {
let dot = self.dot(&rhs);
(dot / (self.mag() * rhs.mag())).acos()
}
pub fn constrain(&mut self, x_rng: &Range<f32>, y_rng: &Range<f32>) {
self.x = self.x.clamp(x_rng.start, x_rng.end);
self.y = self.y.clamp(y_rng.start, y_rng.end);
}
pub fn cross(&mut self) {
self.swap_system(CARTESIAN);
let x = self.x;
self.x = self.y;
self.y = -x;
}
pub fn dist(&self, rhs: &Vec2) -> f32 {
((self.x - rhs.x).powf(2.0)) + ((self.y - rhs.y).powf(2.0)).sqrt()
}
pub fn dist_sq(&self, rhs: &Vec2) -> f32 {
((self.x - rhs.x).powf(2.0)) + ((self.y - rhs.y).powf(2.0))
}
pub fn dbg(&self) {
dbg!(self);
}
pub fn dot(&self, rhs: &Vec2) -> f32 {
(self.x * rhs.x) + (self.y * rhs.y)
}
pub fn div(&mut self, rhs: &f32) {
self.x /= rhs;
self.y /= rhs;
}
pub fn div2(&mut self, rhs: &Vec2) {
self.x /= rhs.x;
self.y /= rhs.y;
}
pub fn lerp(&mut self, rhs: &Vec2, amt: UnitF) {
self.swap_system(CARTESIAN);
self.x = -(amt.value() - 1.0) * self.x + (amt.value() * rhs.x);
self.y = -(amt.value() - 1.0) * self.y + (amt.value() * rhs.y);
}
pub fn mag(&self) -> f32 {
((self.x).powf(2.0) + (self.y).powf(2.0)).sqrt()
}
pub fn mag_sq(&self) -> f32 {
(self.x).powf(2.0) + (self.y).powf(2.0)
}
pub fn mult(&mut self, rhs: &f32) {
self.swap_system(CARTESIAN);
self.x *= rhs;
self.y *= rhs;
}
pub fn mult2(&mut self, rhs: &Vec2) {
self.swap_system(CARTESIAN);
self.x *= rhs.x;
self.y *= rhs.y;
}
pub fn norm(&mut self) {
self.swap_system(POLAR);
self.x = 1.0;
self.swap_system(CARTESIAN);
}
pub fn rem(&mut self, rhs: &f32) {
self.swap_system(CARTESIAN);
self.x %= rhs;
self.y %= rhs;
}
pub fn rotate(&mut self, theta: f32) {
self.swap_system(POLAR);
self.y += theta;
self.swap_system(CARTESIAN);
}
pub fn set(&mut self, input1: &f32, input2: &f32, coord_system: &CoordSystem) {
if *coord_system == CARTESIAN {
self.swap_system(CARTESIAN);
self.x = *input1;
self.y = *input2;
} else {
self.swap_system(POLAR);
self.x = *input1;
self.y = *input2;
self.swap_system(CARTESIAN);
}
}
pub fn set_mag(&mut self, input: &f32) {
self.swap_system(POLAR);
self.x = *input;
self.swap_system(CARTESIAN);
}
pub fn set_theta(&mut self, input: &f32) {
self.swap_system(POLAR);
self.y = *input;
self.swap_system(CARTESIAN);
}
pub fn sub(&mut self, rhs: &Vec2) {
self.swap_system(CARTESIAN);
self.x -= rhs.x;
self.y -= rhs.y;
}
pub fn system(&self) -> CoordSystem {
self.coord_system
}
fn swap_system(&mut self, new_coord_system: CoordSystem) {
if self.coord_system == CARTESIAN && new_coord_system == POLAR {
let x = self.x;
self.x = (self.x.powi(2) + self.y.powi(2)).sqrt();
self.y = self.y.atan2(x);
self.coord_system = new_coord_system;
} else if self.coord_system == POLAR && new_coord_system == CARTESIAN {
let theta = self.y;
self.y = self.x * self.y.sin();
self.x *= theta.cos();
self.coord_system = new_coord_system;
}
}
pub fn theta(&self) -> f32 {
(self.y).atan2(self.x)
}
}
#[derive(Copy, Clone, Debug)]
pub struct Vec3 {
pub x: f32,
pub y: f32,
pub z: f32,
coord_system: CoordSystem,
}
impl Default for Vec3 {
fn default() -> Self {
Self {
x: 0.0,
y: 0.0,
z: 0.0,
coord_system: CARTESIAN,
}
}
}
impl Add for Vec3 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
z: self.z + rhs.z,
coord_system: self.coord_system,
}
}
}
impl AddAssign for Vec3 {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl Sub for Vec3 {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
z: self.z - rhs.z,
coord_system: self.coord_system,
}
}
}
impl SubAssign for Vec3 {
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
impl Mul for Vec3 {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self {
x: self.x * rhs.x,
y: self.y * rhs.y,
z: self.z * rhs.z,
coord_system: self.coord_system,
}
}
}
impl MulAssign for Vec3 {
fn mul_assign(&mut self, rhs: Self) {
*self = *self * rhs;
}
}
impl Div for Vec3 {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self {
x: self.x / rhs.x,
y: self.y / rhs.y,
z: self.z / rhs.z,
coord_system: self.coord_system,
}
}
}
impl DivAssign for Vec3 {
fn div_assign(&mut self, rhs: Self) {
*self = *self / rhs;
}
}
impl Rem for Vec3 {
type Output = Self;
fn rem(self, rhs: Self) -> Self::Output {
Self {
x: self.x % rhs.x,
y: self.y % rhs.y,
z: self.z % rhs.z,
coord_system: self.coord_system,
}
}
}
impl RemAssign for Vec3 {
fn rem_assign(&mut self, rhs: Self) {
*self = *self % rhs;
}
}
impl PartialEq for Vec3 {
fn eq(&self, rhs: &Self) -> bool {
let temp = *self - *rhs;
if temp.x.abs() < 0.00001
&& temp.y.abs() < 0.00001
&& temp.z.abs() < 0.00001
&& self.coord_system == rhs.coord_system
{
true
} else {
false
}
}
fn ne(&self, rhs: &Self) -> bool {
let temp = *self - *rhs;
if temp.x.abs() > 0.00001 || temp.y.abs() > 0.00001 || temp.z.abs() > 0.00001 {
true
} else {
false
}
}
}
impl Vec3 {
pub fn new(x: &f32, y: &f32, z: &f32) -> Vec3 {
let temp = Vec3 {
x: *x,
y: *y,
z: *z,
coord_system: CARTESIAN,
};
temp
}
pub fn create_random(range_x: &Range<f32>) -> Vec3 {
let temp = Vec3 {
x: rand::thread_rng().gen_range(range_x.clone()),
y: rand::thread_rng().gen_range(range_x.clone()),
z: rand::thread_rng().gen_range(range_x.clone()),
coord_system: CARTESIAN,
};
temp
}
pub fn create_random3(
range_x: &Range<f32>,
range_y: &Range<f32>,
range_z: &Range<f32>,
) -> Vec3 {
let temp = Vec3 {
x: rand::thread_rng().gen_range(range_x.clone()),
y: rand::thread_rng().gen_range(range_y.clone()),
z: rand::thread_rng().gen_range(range_z.clone()),
coord_system: CARTESIAN,
};
temp
}
pub fn from_angle(theta: &f32, phi: &f32, in_mag: &Option<f32>) -> Vec3 {
if let Some(mag) = in_mag {
let mut temp = Vec3 {
x: *mag,
y: *theta,
z: *phi,
coord_system: POLAR,
};
temp.swap_system(CARTESIAN);
temp
} else {
let mut temp = Vec3 {
x: 1.0,
y: *theta,
z: *phi,
coord_system: POLAR,
};
temp.swap_system(CARTESIAN);
temp
}
}
pub fn from_rand_angle(range: &Range<f32>, mag: &Option<f32>) -> Vec3 {
let temp = Vec3::from_angle(
&rand::thread_rng().gen_range(range.clone()),
&rand::thread_rng().gen_range(range.clone()),
mag,
);
temp
}
pub fn random_unit(range: &Range<f32>) -> Vec3 {
let temp = Vec3::from_angle(
&rand::thread_rng().gen_range(range.clone()),
&rand::thread_rng().gen_range(range.clone()),
&None,
);
temp
}
pub fn unit() -> Vec3 {
let temp = Vec3::from_angle(&0.0, &0.0, &Some(1.0));
temp
}
pub fn add(&mut self, rhs: &Vec3) {
self.swap_system(CARTESIAN);
self.x += rhs.x;
self.y += rhs.y;
self.z += rhs.z;
}
pub fn angle_between(&self, rhs: &Vec3) -> f32 {
let dot = self.dot(&rhs);
(dot / (self.mag() * rhs.mag())).acos()
}
pub fn constrain(&mut self, x_rng: &Range<f32>, y_rng: &Range<f32>, z_rng: &Range<f32>) {
self.x = self.x.clamp(x_rng.start, x_rng.end);
self.y = self.y.clamp(y_rng.start, y_rng.end);
self.z = self.z.clamp(z_rng.start, z_rng.end);
}
pub fn cross(&mut self, rhs: &Vec3) -> Vec3 {
self.swap_system(CARTESIAN);
let x = (self.y * rhs.z) - (self.z * rhs.y);
let y = (self.z * rhs.x) - (self.x * rhs.z);
let z = (self.x * rhs.y) - (self.y * rhs.x);
Vec3 {
x,
y,
z,
coord_system: CARTESIAN,
}
}
pub fn dist(&self, rhs: &Vec3) -> f32 {
let distance = ((self.x - rhs.x).powf(2.0))
+ ((self.y - rhs.y).powf(2.0))
+ ((self.z - rhs.z).powf(2.0));
distance.sqrt()
}
pub fn dist_sq(&self, rhs: &Vec3) -> f32 {
let distance = ((self.x - rhs.x).powf(2.0))
+ ((self.y - rhs.y).powf(2.0))
+ ((self.z - rhs.z).powf(2.0));
distance
}
pub fn dbg(&self) {
dbg!(self);
}
pub fn dot(&self, rhs: &Vec3) -> f32 {
(self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
}
pub fn div(&mut self, rhs: &f32) {
self.x /= rhs;
self.y /= rhs;
self.z /= rhs;
}
pub fn div2(&mut self, rhs: &Vec3) {
self.x /= rhs.x;
self.y /= rhs.y;
self.z /= rhs.z;
}
pub fn lerp(&mut self, rhs: &Vec3, amt: UnitF) {
self.swap_system(CARTESIAN);
self.x = -(amt.value() - 1.0) * self.x + (amt.value() * rhs.x);
self.y = -(amt.value() - 1.0) * self.y + (amt.value() * rhs.y);
self.z = -(amt.value() - 1.0) * self.z + (amt.value() * rhs.z);
}
pub fn mag(&self) -> f32 {
(self.x.powf(2.0) + self.y.powf(2.0) + self.z.powf(2.0)).sqrt()
}
pub fn mag_sq(&self) -> f32 {
self.x.powf(2.0) + self.y.powf(2.0) + self.z.powf(2.0)
}
pub fn mult(&mut self, rhs: &f32) {
self.swap_system(CARTESIAN);
self.x *= rhs;
self.y *= rhs;
self.z *= rhs;
}
pub fn mult2(&mut self, rhs: &Vec3) {
self.swap_system(CARTESIAN);
self.x *= rhs.x;
self.y *= rhs.y;
self.z *= rhs.z;
}
pub fn norm(&mut self) {
self.swap_system(POLAR);
self.x = 1.0;
self.swap_system(CARTESIAN);
}
pub fn phi(&self) -> f32 {
self.x * (self.y).cos()
}
pub fn rem(&mut self, rhs: &f32) {
self.swap_system(CARTESIAN);
self.x %= rhs;
self.y %= rhs;
self.z %= rhs;
}
pub fn rotate(&mut self, theta: &f32, phi: &f32) {
self.swap_system(POLAR);
self.y += *theta;
self.z += *phi;
self.swap_system(CARTESIAN);
}
pub fn set(&mut self, input1: &f32, input2: &f32, input3: &f32, coord_system: &CoordSystem) {
if *coord_system == CARTESIAN {
self.swap_system(CARTESIAN);
self.x = *input1;
self.y = *input2;
self.z = *input3;
} else {
self.swap_system(POLAR);
self.x = *input1;
self.y = *input2;
self.z = *input3;
self.swap_system(CARTESIAN);
}
}
pub fn set_mag(&mut self, input: &f32) {
self.swap_system(POLAR);
self.x = *input;
self.swap_system(CARTESIAN);
}
pub fn set_theta(&mut self, input: &f32) {
self.swap_system(POLAR);
self.y = *input;
self.swap_system(CARTESIAN);
}
pub fn set_phi(&mut self, input: &f32) {
self.swap_system(POLAR);
self.z = *input;
self.swap_system(CARTESIAN);
}
pub fn sub(&mut self, rhs: &Vec3) {
self.swap_system(CARTESIAN);
self.x -= rhs.x;
self.y -= rhs.y;
self.z -= rhs.z;
}
pub fn system(&self) -> CoordSystem {
self.coord_system
}
fn swap_system(&mut self, new_coord_system: CoordSystem) {
if self.coord_system == CARTESIAN && new_coord_system == POLAR {
let x = self.x;
let y = self.y;
self.x = (self.x.powf(2.0) + self.y.powf(2.0)).sqrt();
self.y = self.z.atan2(x);
self.z = y.atan2(x);
self.coord_system = new_coord_system;
} else if self.coord_system == POLAR && new_coord_system == CARTESIAN {
let mag = self.x;
let theta = self.y;
self.y = self.x * self.y.sin() * self.z.cos();
self.x = self.x * theta.sin() * self.z.sin();
self.z = mag * theta.cos();
self.coord_system = new_coord_system;
}
}
pub fn theta(&self) -> f32 {
(self.z).atan2(self.x)
}
}