Alex Mikhalev
6 years ago
6 changed files with 609 additions and 280 deletions
@ -0,0 +1,276 @@
@@ -0,0 +1,276 @@
|
||||
use super::{Scalar, Value}; |
||||
|
||||
use std::ops; |
||||
|
||||
#[derive(Clone, PartialEq, Debug)] |
||||
pub struct Vec2<T> { |
||||
pub x: T, |
||||
pub y: T, |
||||
} |
||||
|
||||
impl<T> Vec2<T> { |
||||
pub fn new(x: T, y: T) -> Self { |
||||
Self { x, y } |
||||
} |
||||
} |
||||
|
||||
impl Vec2<Scalar> { |
||||
pub fn normal2(self) -> Scalar { |
||||
self.x * self.x + self.y * self.y |
||||
} |
||||
|
||||
pub fn normal(self) -> Scalar { |
||||
self.normal2().sqrt() |
||||
} |
||||
|
||||
pub fn normalize(self) -> Vec2<Scalar> { |
||||
self.clone() / self.normal() |
||||
} |
||||
} |
||||
|
||||
impl Vec2<Value> { |
||||
pub fn simplify(self) -> Self { |
||||
Self { |
||||
x: self.x.simplify(), |
||||
y: self.y.simplify(), |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Add<U>, U> ops::Add<Vec2<U>> for Vec2<T> { |
||||
type Output = Vec2<T::Output>; |
||||
fn add(self, rhs: Vec2<U>) -> Self::Output { |
||||
Self::Output { |
||||
x: self.x + rhs.x, |
||||
y: self.y + rhs.y, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Sub<U>, U> ops::Sub<Vec2<U>> for Vec2<T> { |
||||
type Output = Vec2<T::Output>; |
||||
fn sub(self, rhs: Vec2<U>) -> Self::Output { |
||||
Self::Output { |
||||
x: self.x - rhs.x, |
||||
y: self.y - rhs.y, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Mul<U>, U: Clone> ops::Mul<U> for Vec2<T> { |
||||
type Output = Vec2<T::Output>; |
||||
fn mul(self, rhs: U) -> Self::Output { |
||||
Self::Output { |
||||
x: self.x * rhs.clone(), |
||||
y: self.y * rhs, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Div<U>, U: Clone> ops::Div<U> for Vec2<T> { |
||||
type Output = Vec2<T::Output>; |
||||
fn div(self, rhs: U) -> Self::Output { |
||||
Self::Output { |
||||
x: self.x / rhs.clone(), |
||||
y: self.y / rhs, |
||||
} |
||||
} |
||||
} |
||||
|
||||
#[derive(Clone, PartialEq, Debug)] |
||||
pub struct Point2<T> { |
||||
pub x: T, |
||||
pub y: T, |
||||
} |
||||
|
||||
impl<T> Point2<T> { |
||||
pub fn new(x: T, y: T) -> Point2<T> { |
||||
Point2 { x, y } |
||||
} |
||||
} |
||||
|
||||
impl Point2<Value> { |
||||
pub fn simplify(self) -> Self { |
||||
Self { |
||||
x: self.x.simplify(), |
||||
y: self.y.simplify(), |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl From<Point2<Scalar>> for Point2<Value> { |
||||
fn from(sp: Point2<Scalar>) -> Self { |
||||
Self { x: sp.x.into(), y: sp.y.into() } |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Add<U>, U> ops::Add<Vec2<U>> for Point2<T> { |
||||
type Output = Point2<T::Output>; |
||||
fn add(self, rhs: Vec2<U>) -> Self::Output { |
||||
Point2 { |
||||
x: self.x + rhs.x, |
||||
y: self.y + rhs.y, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Sub<U>, U> ops::Sub<Vec2<U>> for Point2<T> { |
||||
type Output = Point2<T::Output>; |
||||
fn sub(self, rhs: Vec2<U>) -> Self::Output { |
||||
Point2 { |
||||
x: self.x - rhs.x, |
||||
y: self.y - rhs.y, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl<T: ops::Sub<U>, U> ops::Sub<Point2<U>> for Point2<T> { |
||||
type Output = Vec2<T::Output>; |
||||
fn sub(self, rhs: Point2<U>) -> Self::Output { |
||||
Vec2 { |
||||
x: self.x - rhs.x, |
||||
y: self.y - rhs.y, |
||||
} |
||||
} |
||||
} |
||||
|
||||
use std::fmt; |
||||
|
||||
impl<T: fmt::Display> fmt::Display for Point2<T> { |
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||
write!(f, "({}, {})", self.x, self.y) |
||||
} |
||||
} |
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug)] |
||||
pub struct Rot2 { |
||||
cos: Scalar, |
||||
sin: Scalar, |
||||
} |
||||
|
||||
impl fmt::Display for Rot2 { |
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
||||
write!(f, "({}, {})", self.cos, self.sin) |
||||
} |
||||
} |
||||
|
||||
impl Rot2 { |
||||
pub fn from_cos_sin_unchecked(cos: Scalar, sin: Scalar) -> Self { |
||||
Self { cos, sin } |
||||
} |
||||
|
||||
pub fn from_cos_sin(cos: Scalar, sin: Scalar) -> Self { |
||||
Vec2 { x: cos, y: sin }.into() |
||||
} |
||||
|
||||
pub fn from_angle(angle: Scalar) -> Self { |
||||
Self { |
||||
cos: angle.cos().into(), |
||||
sin: angle.sin().into(), |
||||
} |
||||
} |
||||
|
||||
pub fn cardinal(index: i64) -> Self { |
||||
match index % 4 { |
||||
0 => Rot2 { |
||||
cos: (1.).into(), |
||||
sin: (0.).into(), |
||||
}, |
||||
1 => Rot2 { |
||||
cos: (0.).into(), |
||||
sin: (1.).into(), |
||||
}, |
||||
2 => Rot2 { |
||||
cos: (-1.).into(), |
||||
sin: (0.).into(), |
||||
}, |
||||
3 => Rot2 { |
||||
cos: (0.).into(), |
||||
sin: (-1.).into(), |
||||
}, |
||||
_ => unreachable!(), |
||||
} |
||||
} |
||||
|
||||
pub fn cos(&self) -> Scalar { |
||||
self.cos |
||||
} |
||||
|
||||
pub fn sin(&self) -> Scalar { |
||||
self.sin |
||||
} |
||||
|
||||
pub fn conj(self) -> Self { |
||||
Self { |
||||
cos: self.cos, |
||||
sin: -self.sin, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl From<Vec2<Scalar>> for Rot2 { |
||||
fn from(v: Vec2<Scalar>) -> Rot2 { |
||||
let v = v.normalize(); |
||||
Rot2 { cos: v.x, sin: v.y } |
||||
} |
||||
} |
||||
|
||||
impl ops::Mul<Scalar> for Rot2 { |
||||
type Output = Vec2<Scalar>; |
||||
fn mul(self, rhs: Scalar) -> Vec2<Scalar> { |
||||
Vec2 { |
||||
x: self.cos * rhs, |
||||
y: self.sin * rhs, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl ops::Mul<Value> for Rot2 { |
||||
type Output = Vec2<Value>; |
||||
fn mul(self, rhs: Value) -> Vec2<Value> { |
||||
Vec2 { |
||||
x: rhs.clone() * self.cos, |
||||
y: rhs * self.sin, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl ops::Add<Rot2> for Rot2 { |
||||
type Output = Rot2; |
||||
fn add(self, rhs: Rot2) -> Rot2 { |
||||
Rot2 { |
||||
cos: self.cos.clone() * rhs.cos.clone() - self.sin.clone() * rhs.sin.clone(), |
||||
sin: self.cos * rhs.sin + self.sin * rhs.cos, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl ops::Sub<Rot2> for Rot2 { |
||||
type Output = Rot2; |
||||
fn sub(self, rhs: Rot2) -> Rot2 { |
||||
Rot2 { |
||||
cos: self.cos.clone() * rhs.cos.clone() + self.sin.clone() * rhs.sin.clone(), |
||||
sin: self.sin * rhs.cos - self.cos * rhs.sin, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl ops::Mul<Vec2<Scalar>> for Rot2 { |
||||
type Output = Vec2<Scalar>; |
||||
fn mul(self, rhs: Vec2<Scalar>) -> Vec2<Scalar> { |
||||
Vec2 { |
||||
x: self.cos * rhs.x - self.sin * rhs.y, |
||||
y: self.cos * rhs.y + self.sin * rhs.x, |
||||
} |
||||
} |
||||
} |
||||
|
||||
impl ops::Mul<Vec2<Value>> for Rot2 { |
||||
type Output = Vec2<Value>; |
||||
fn mul(self, rhs: Vec2<Value>) -> Vec2<Value> { |
||||
Vec2 { |
||||
x: rhs.x.clone() * self.cos - rhs.y.clone() * self.sin, |
||||
y: rhs.y * self.cos + rhs.x * self.sin, |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue