use std::ops::Range;
#[derive(Clone, Copy)]
pub struct Vector {
pub x: f64,
pub y: f64,
}
#[derive(Clone, Copy)]
pub struct Point {
pub x: f64,
pub y: f64,
}
pub struct Bounds<T> {
pub x: Range<T>,
pub y: Range<T>
}
impl Vector {
pub fn new(x: f64, y: f64) -> Vector {
Vector { x, y }
}
pub fn norm(&self) -> f64 {
(self.x * self.x + self.y * self.y).sqrt()
}
pub fn rotate_ccw(&self) -> Vector {
(- self.y, self.x).into()
}
pub fn rotate_cw(&self) -> Vector {
( self.y, -self.x).into()
}
}
impl Point {
pub fn new(x: f64, y: f64) -> Point {
Point { x, y }
}
}
impl<T> From<(Range<T>, Range<T>)> for Bounds<T> {
fn from((x, y): (Range<T>, Range<T>)) -> Self {
Bounds { x, y }
}
}
impl std::ops::Add<Vector> for Vector {
type Output = Vector;
fn add(self, other: Self) -> Vector {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::Add<&Vector> for Vector {
type Output = Vector;
fn add(self, other: &Self) -> Vector {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::Add<Vector> for &Vector {
type Output = Vector;
fn add(self, other: Vector) -> Vector {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::Add<&Vector> for &Vector {
type Output = Vector;
fn add(self, other: &Vector) -> Vector {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::AddAssign<Vector> for Vector {
fn add_assign(&mut self, other: Self) {
self.x += other.x;
self.y += other.y;
}
}
impl std::ops::AddAssign<&Vector> for Vector {
fn add_assign(&mut self, other: &Self) {
self.x += other.x;
self.y += other.y;
}
}
impl std::ops::Sub<Vector> for Vector {
type Output = Vector;
fn sub(self, other: Self) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Sub<&Vector> for Vector {
type Output = Vector;
fn sub(self, other: &Self) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Sub<Vector> for &Vector {
type Output = Vector;
fn sub(self, other: Vector) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Sub<&Vector> for &Vector {
type Output = Vector;
fn sub(self, other: &Vector) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::SubAssign<Vector> for Vector {
fn sub_assign(&mut self, other: Self) {
self.x -= other.x;
self.y -= other.y;
}
}
impl std::ops::SubAssign<&Vector> for Vector {
fn sub_assign(&mut self, other: &Self) {
self.x -= other.x;
self.y -= other.y;
}
}
impl std::ops::Mul<Vector> for Vector {
type Output = f64;
fn mul(self, other: Self) -> f64 {
self.x * other.x + self.y * other.y
}
}
impl std::ops::Mul<Vector> for &Vector {
type Output = f64;
fn mul(self, other: Vector) -> f64 {
self.x * other.x + self.y * other.y
}
}
impl std::ops::Mul<&Vector> for Vector {
type Output = f64;
fn mul(self, other: &Self) -> f64 {
self.x * other.x + self.y * other.y
}
}
impl std::ops::Mul for &Vector {
type Output = f64;
fn mul(self, other: &Vector) -> f64 {
self.x * other.x + self.y * other.y
}
}
impl std::ops::Mul<f64> for Vector {
type Output = Vector;
fn mul(self, scalar: f64) -> Vector {
(self.x * scalar, self.y * scalar).into()
}
}
impl std::ops::Mul<f64> for &Vector {
type Output = Vector;
fn mul(self, scalar: f64) -> Vector {
(self.x * scalar, self.y * scalar).into()
}
}
impl std::ops::Mul<Vector> for f64 {
type Output = Vector;
fn mul(self, p: Vector) -> Vector {
(self * p.x, self * p.y).into()
}
}
impl std::ops::Mul<&Vector> for f64 {
type Output = Vector;
fn mul(self, p: &Vector) -> Vector {
(self * p.x, self * p.y).into()
}
}
impl std::ops::MulAssign<f64> for Vector {
fn mul_assign(&mut self, scalar: f64) {
self.x *= scalar;
self.y *= scalar;
}
}
impl std::ops::Div<f64> for Vector {
type Output = Vector;
fn div(self, scalar: f64) -> Vector {
(self.x / scalar, self.y / scalar).into()
}
}
impl std::ops::Div<f64> for &Vector {
type Output = Vector;
fn div(self, scalar: f64) -> Vector {
(self.x / scalar, self.y / scalar).into()
}
}
impl std::ops::DivAssign<f64> for Vector {
fn div_assign(&mut self, scalar: f64) {
self.x /= scalar;
self.y /= scalar;
}
}
impl std::ops::Neg for Vector {
type Output = Vector;
fn neg(self) -> Self {
(-self.x, -self.y).into()
}
}
impl std::ops::Neg for &Vector {
type Output = Vector;
fn neg(self) -> Vector {
(-self.x, -self.y).into()
}
}
impl std::ops::Sub<Point> for Point {
type Output = Vector;
fn sub(self, other: Self) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Sub<&Point> for Point {
type Output = Vector;
fn sub(self, other: &Self) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Sub<Point> for &Point {
type Output = Vector;
fn sub(self, other: Point) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Sub<&Point> for &Point {
type Output = Vector;
fn sub(self, other: &Point) -> Vector {
(self.x - other.x, self.y - other.y).into()
}
}
impl std::ops::Add<Vector> for Point {
type Output = Point;
fn add(self, other: Vector) -> Point {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::Add<&Vector> for Point {
type Output = Point;
fn add(self, other: &Vector) -> Point {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::Add<Vector> for &Point {
type Output = Point;
fn add(self, other: Vector) -> Point {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::Add<&Vector> for &Point {
type Output = Point;
fn add(self, other: &Vector) -> Point {
(self.x + other.x, self.y + other.y).into()
}
}
impl std::ops::AddAssign<Vector> for Point {
fn add_assign(&mut self, other: Vector) {
self.x += other.x;
self.y += other.y;
}
}
impl std::ops::AddAssign<&Vector> for Point {
fn add_assign(&mut self, other: &Vector) {
self.x += other.x;
self.y += other.y;
}
}
impl From<(f64, f64)> for Vector {
fn from((x, y): (f64, f64)) -> Self {
Vector { x, y }
}
}
impl From<Vector> for (f64, f64) {
fn from(p: Vector) -> Self {
(p.x, p.y)
}
}
impl From<(f64, f64)> for Point {
fn from((x, y): (f64, f64)) -> Self {
Point { x, y }
}
}
impl From<Point> for (f64, f64) {
fn from(p: Point) -> Self {
(p.x, p.y)
}
}
impl From<Point> for Vector {
fn from(p: Point) -> Self {
Vector { x: p.x, y: p.y }
}
}
impl From<Vector> for Point {
fn from(v: Vector) -> Self {
Point { x: v.x, y: v.y }
}
}
pub trait VectorMath: Sized {
fn dot(&self, other: &Self) -> f64;
fn add(&self, other: &Self) -> Self;
fn sub(&self, other: &Self) -> Self;
fn mul(&self, scalar: f64) -> Self;
fn mul_pt(&self, other: &Self) -> Self;
fn norm(&self) -> f64 {
self.dot(self).sqrt()
}
fn normalized(&self) -> Self {
self.mul(1.0 / self.norm())
}
}
impl VectorMath for Vec<f64> {
fn dot(&self, other: &Self) -> f64 {
self.iter().zip(other.iter()).map(|(x, y)| x * y).sum::<f64>()
}
fn add(&self, other: &Self) -> Self {
self.iter().zip(other.iter()).map(|(x, y)| x + y).collect()
}
fn sub(&self, other: &Self) -> Self {
self.iter().zip(other.iter()).map(|(x, y)| x - y).collect()
}
fn mul(&self, scalar: f64) -> Self {
self.iter().map(|x| scalar * x).collect()
}
fn mul_pt(&self, other: &Self) -> Self {
self.iter().zip(other.iter()).map(|(x, y)| x * y).collect()
}
}
impl VectorMath for (f64, f64) {
fn dot(&self, other: &Self) -> f64 {
self.0 * other.0 + self.1 * other.1
}
fn add(&self, other: &Self) -> Self {
(self.0 + other.0, self.1 + other.1)
}
fn sub(&self, other: &Self) -> Self {
(self.0 - other.0, self.1 - other.1)
}
fn mul(&self, scalar: f64) -> Self {
(scalar * self.0, scalar * self.1)
}
fn mul_pt(&self, other: &Self) -> Self {
(self.0 * other.0, self.1 * other.1)
}
}