Alex Mikhalev
6 years ago
6 changed files with 609 additions and 280 deletions
@ -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