use std::fmt::{Display, Formatter};
use std::ops::{Add, Div, Mul, Sub};
pub mod vector_2_to_decimal;
pub mod mul;
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Vector2<T> {
x: T,
y: T
}
impl<T> Vector2<T> {
pub fn new(x: T, y: T) -> Vector2<T> {
Self {
x,
y
}
}
pub fn cast_to<R: From<T>>(self) -> Vector2<R> {
Vector2::<R> {
x: R::from(self.x),
y: R::from(self.y),
}
}
}
impl<T: Add<Output=T>+Mul<Output=T>+Copy> Vector2<T> {
pub fn square_magnitude(&self) -> T {
(self.x * self.x) + (self.y * self.y)
}
}
impl<T: Mul<Output=T>+Add<Output=T>+Sub<Output=T>+Copy> Vector2<T> {
pub fn square_distance(&self, from: &Vector2<T>) -> T {
let x_dist = from.x - self.x;
let y_dist = from.y - self.y;
return (x_dist * x_dist) + (y_dist * y_dist);
}
}
impl Vector2<f32> {
pub fn magnitude(&self) -> f32 {
self.square_magnitude().sqrt()
}
pub fn distance(&self, other: &Vector2<f32>) -> f32 {
self.square_distance(other).sqrt()
}
}
impl Vector2<f64> {
pub fn magnitude(&self) -> f64 {
self.square_magnitude().sqrt()
}
pub fn distance(&self, other: &Vector2<f64>) -> f64 {
self.square_distance(other).sqrt()
}
}
impl<T> From<(T, T)> for Vector2<T> {
fn from(value: (T, T)) -> Self {
Vector2::new(value.0, value.1)
}
}
impl<T: Display> Display for Vector2<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
impl<T:Default> Default for Vector2<T> {
fn default() -> Self {
Self {
x: T::default(),
y: T::default(),
}
}
}
impl<T> Add for Vector2<T> where T: Add<Output = T>{
type Output = Vector2<T>;
fn add(self, rhs: Self) -> Self::Output {
Self {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
impl<T> Sub for Vector2<T> where T: Sub<Output = T>{
type Output = Vector2<T>;
fn sub(self, rhs: Self) -> Self::Output {
Self {
x: self.x - rhs.x,
y: self.y - rhs.y,
}
}
}
impl<T> Mul<T> for Vector2<T> where T: Mul<Output = T> + Copy {
type Output = Vector2<T>;
fn mul(self, scalar: T) -> Self::Output {
Self {
x: self.x * scalar.clone(),
y: self.y * scalar,
}
}
}
impl<T> Div<T> for Vector2<T> where T: Div<Output = T> + Copy {
type Output = Vector2<T>;
fn div(self, scalar: T) -> Self::Output {
Self {
x: self.x / scalar.clone(),
y: self.y / scalar,
}
}
}
#[cfg(test)]
mod tests {
use crate::vector_2_to_decimal::{Vector2ToDouble, Vector2ToFloat};
use super::*;
#[test]
fn convert_i32_f32() {
let v1 = Vector2::new(3, 4);
let v2 = v1.to_float();
assert_eq!(v2, Vector2::new(3.0, 4.0))
}
#[test]
fn convert_i32_f64() {
let v1 = Vector2::new(3, 4);
let v2 = v1.to_double();
assert_eq!(v2, Vector2::new(3.0, 4.0))
}
#[test]
fn cast_i32_i64() {
let v1 = Vector2::new(3, 4);
let v2: Vector2<i64> = v1.cast_to();
assert_eq!(v2, Vector2::new(3, 4))
}
#[test]
fn add() {
let v1 = Vector2::new(1, 2);
let v2 = Vector2::new(2, 2);
assert_eq!(v1 + v2, Vector2::new(3, 4))
}
#[test]
fn sub() {
let v1 = Vector2::new(1, 2);
let v2 = Vector2::new(2, 2);
assert_eq!(v2 - v1, Vector2::new(1, 0))
}
#[test]
fn mul() {
let v1 = Vector2::new(1, 1);
let v2 = 2 * v1;
assert_eq!(v2, Vector2::new(2, 2))
}
#[test]
fn div() {
let v1 = Vector2::new(2, 2);
let v2 = v1 / 2;
assert_eq!(v2, Vector2::new(1, 1))
}
}