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