diff --git a/src/entity.rs b/src/entity.rs index be31660..3f10f8b 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -1,8 +1,8 @@ use std::cell::RefCell; use std::rc::Rc; +use crate::math::eqn::Eqns; use crate::math::{Point2, Region, Region1, Region2, Scalar}; -use crate::math::eqn::{Eqns}; use std::fmt; type EntityId = i64; @@ -14,7 +14,9 @@ pub struct Constrainable> { constraints: TRegion, } -impl + fmt::Display> fmt::Display for Constrainable { +impl + fmt::Display> fmt::Display + for Constrainable +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{{ {} ∈ {} }}", self.value, self.constraints) } @@ -22,7 +24,11 @@ impl + fmt::Display> fmt::Display fo impl + Clone> Constrainable { pub fn new(value: T, constraints: TRegion) -> Self { - Self { id: 0, value, constraints } + Self { + id: 0, + value, + constraints, + } } pub fn new_full(value: T) -> Self { diff --git a/src/main.rs b/src/main.rs index 3e7889d..ae784b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ mod relation; fn main() { use entity::{CPoint, PointRef}; - use math::{Point2, Expr, Region2, Rot2, Eqn, Eqns}; + use math::{Eqn, Eqns, Expr, Point2, Region2, Rot2}; use relation::{Relation, ResolveResult}; env_logger::init(); @@ -30,14 +30,21 @@ fn main() { // let u2 = eqn::Expr::from(1.); let origin = CPoint::new_single(Point2::new((0.).into(), (0.).into())).into_ref(); // let p1 = Point::new_ref(Var::new_full(Point2::new((1.).into(), (1.).into()))); - let p1 = CPoint::new(Point2::new(0.,0.), Region2::Singleton(Point2::new((u1).into(), (u2).into()))).into_ref(); + let p1 = CPoint::new( + Point2::new(0., 0.), + Region2::Singleton(Point2::new((u1).into(), (u2).into())), + ) + .into_ref(); let p2 = CPoint::new_full(Point2::new((4.).into(), (4.).into())).into_ref(); let p3 = CPoint::new_full(Point2::new((2.).into(), (2.).into())).into_ref(); let mut points: Vec = vec![origin.clone(), p1.clone(), p2.clone(), p3.clone()]; let print_points = |points: &Vec| { println!( "origin: {}\np1: {}\np2: {}\np3: {}", - points[0].borrow(), points[1].borrow(), points[2].borrow(), points[3].borrow(), + points[0].borrow(), + points[1].borrow(), + points[2].borrow(), + points[3].borrow(), ); }; print_points(&points); @@ -49,8 +56,12 @@ fn main() { let c3 = relation::PointAngle::new_horizontal(p2.clone(), p3.clone()); let c2 = relation::AlignedDistance::new_vertical(p1.clone(), p2.clone(), 12.); let c5 = relation::PointAngle::new(p1.clone(), p3.clone(), Rot2::from_angle_deg(0.572938698)); - let mut relations: Vec> = - vec![/*Box::new(c1),*/ Box::new(c2), Box::new(c3), Box::new(c4), Box::new(c5)]; + let mut relations: Vec> = vec![ + /*Box::new(c1),*/ Box::new(c2), + Box::new(c3), + Box::new(c4), + Box::new(c5), + ]; let mut constrained: Vec> = Vec::new(); let mut any_underconstrained = true; let mut any_constrained = true; diff --git a/src/math/eqn.rs b/src/math/eqn.rs index 154e767..a9ff202 100644 --- a/src/math/eqn.rs +++ b/src/math/eqn.rs @@ -1,8 +1,8 @@ use std::fmt; -use super::Scalar; use super::expr::Expr; use super::unknown::*; +use super::Scalar; #[derive(Clone, Debug, PartialEq)] pub struct Eqn(pub Expr, pub Expr); diff --git a/src/math/expr.rs b/src/math/expr.rs index 2ab68e8..3e52633 100644 --- a/src/math/expr.rs +++ b/src/math/expr.rs @@ -1,9 +1,9 @@ use std::collections::BTreeMap; use std::fmt; -use super::Scalar; use super::eqn::Eqns; -use super::unknown::{Unknown, Unknowns, UnknownSet}; +use super::unknown::{Unknown, UnknownSet, Unknowns}; +use super::Scalar; #[derive(Clone, Debug, PartialEq)] pub enum Expr { @@ -127,11 +127,11 @@ fn product_fold(l: Expr, r: Expr) -> Expr { (Product(mut ls), Product(mut rs)) => { ls.append(&mut rs); Product(ls) - }, + } (Product(mut ps), o) | (o, Product(mut ps)) => { ps.push(o); Product(ps) - }, + } (l, r) => Expr::new_product(l, r), } } @@ -143,22 +143,20 @@ fn group_product(es: Exprs) -> Exprs { let mut other = Exprs::new(); for e in es { let unkns = e.unknowns(); - match e { + match e { Const(c) => match consts { None => consts = Some(c), Some(cs) => consts = Some(c * cs), - } - e => { - other.push(e) - } + }, + e => other.push(e), } } - if let Some(cs) = consts { + if let Some(cs) = consts { if relative_eq!(cs, 0.0) { other.clear(); other.push(Const(0.0)) } else if relative_ne!(cs, 1.0) { - other.push(Const(cs)) + other.push(Const(cs)) } }; trace!("group product: {:?} => {:?}", es2, other); @@ -457,4 +455,4 @@ impl fmt::Display for Expr { Neg(e) => write!(f, "-({})", e), } } -} \ No newline at end of file +} diff --git a/src/math/mod.rs b/src/math/mod.rs index e36076f..96fcbab 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,4 +1,3 @@ - pub mod eqn; pub mod expr; pub mod ops; @@ -8,9 +7,9 @@ pub mod vec; pub use eqn::{Eqn, Eqns}; pub use expr::{Expr, Exprs}; -pub use unknown::{Unknown, Unknowns, UnknownSet}; -pub use region::{Region, Region1, Line2, Region2, GenericRegion}; pub use ops::*; +pub use region::{GenericRegion, Line2, Region, Region1, Region2}; +pub use unknown::{Unknown, UnknownSet, Unknowns}; pub use vec::*; pub type Scalar = f64; diff --git a/src/math/ops.rs b/src/math/ops.rs index 6a03ed7..176857c 100644 --- a/src/math/ops.rs +++ b/src/math/ops.rs @@ -3,195 +3,195 @@ use std::ops; use super::{Expr, Scalar, Unknown}; impl From for Expr { - fn from(c: Scalar) -> Expr { - Expr::Const(c) - } + fn from(c: Scalar) -> Expr { + Expr::Const(c) + } } impl From for Expr { - fn from(u: Unknown) -> Expr { - Expr::Unkn(u) - } + fn from(u: Unknown) -> Expr { + Expr::Unkn(u) + } } impl ops::Add for Expr { - type Output = Expr; - fn add(self, rhs: Expr) -> Expr { - Expr::new_sum(self, rhs) - } + type Output = Expr; + fn add(self, rhs: Expr) -> Expr { + Expr::new_sum(self, rhs) + } } impl ops::Add for Expr { - type Output = Expr; - fn add(self, rhs: Scalar) -> Expr { - Expr::new_sum(self, rhs.into()) - } + type Output = Expr; + fn add(self, rhs: Scalar) -> Expr { + Expr::new_sum(self, rhs.into()) + } } impl ops::Add for Expr { - type Output = Expr; - fn add(self, rhs: Unknown) -> Expr { - Expr::new_sum(self, rhs.into()) - } + type Output = Expr; + fn add(self, rhs: Unknown) -> Expr { + Expr::new_sum(self, rhs.into()) + } } impl ops::Sub for Expr { - type Output = Expr; - fn sub(self, rhs: Expr) -> Expr { - Expr::new_minus(self, rhs) - } + type Output = Expr; + fn sub(self, rhs: Expr) -> Expr { + Expr::new_minus(self, rhs) + } } impl ops::Sub for Expr { - type Output = Expr; - fn sub(self, rhs: Scalar) -> Expr { - Expr::new_minus(self, rhs.into()) - } + type Output = Expr; + fn sub(self, rhs: Scalar) -> Expr { + Expr::new_minus(self, rhs.into()) + } } impl ops::Sub for Expr { - type Output = Expr; - fn sub(self, rhs: Unknown) -> Expr { - Expr::new_minus(self, rhs.into()) - } + type Output = Expr; + fn sub(self, rhs: Unknown) -> Expr { + Expr::new_minus(self, rhs.into()) + } } impl ops::Mul for Expr { - type Output = Expr; - fn mul(self, rhs: Expr) -> Expr { - Expr::new_product(self, rhs) - } + type Output = Expr; + fn mul(self, rhs: Expr) -> Expr { + Expr::new_product(self, rhs) + } } impl ops::Mul for Expr { - type Output = Expr; - fn mul(self, rhs: Scalar) -> Expr { - Expr::new_product(self, rhs.into()) - } + type Output = Expr; + fn mul(self, rhs: Scalar) -> Expr { + Expr::new_product(self, rhs.into()) + } } impl ops::Mul for Expr { - type Output = Expr; - fn mul(self, rhs: Unknown) -> Expr { - Expr::new_product(self, rhs.into()) - } + type Output = Expr; + fn mul(self, rhs: Unknown) -> Expr { + Expr::new_product(self, rhs.into()) + } } impl ops::Div for Expr { - type Output = Expr; - fn div(self, rhs: Expr) -> Expr { - Expr::new_div(self, rhs) - } + type Output = Expr; + fn div(self, rhs: Expr) -> Expr { + Expr::new_div(self, rhs) + } } impl ops::Div for Expr { - type Output = Expr; - fn div(self, rhs: Scalar) -> Expr { - Expr::new_div(self, rhs.into()) - } + type Output = Expr; + fn div(self, rhs: Scalar) -> Expr { + Expr::new_div(self, rhs.into()) + } } impl ops::Div for Expr { - type Output = Expr; - fn div(self, rhs: Unknown) -> Expr { - Expr::new_div(self, rhs.into()) - } + type Output = Expr; + fn div(self, rhs: Unknown) -> Expr { + Expr::new_div(self, rhs.into()) + } } impl ops::Neg for Expr { - type Output = Expr; - fn neg(self) -> Expr { - Expr::new_neg(self) - } + type Output = Expr; + fn neg(self) -> Expr { + Expr::new_neg(self) + } } impl ops::Add for Unknown { - type Output = Expr; - fn add(self, rhs: Expr) -> Expr { - Expr::new_sum(self.into(), rhs) - } + type Output = Expr; + fn add(self, rhs: Expr) -> Expr { + Expr::new_sum(self.into(), rhs) + } } impl ops::Add for Unknown { - type Output = Expr; - fn add(self, rhs: Scalar) -> Expr { - Expr::new_sum(self.into(), rhs.into()) - } + type Output = Expr; + fn add(self, rhs: Scalar) -> Expr { + Expr::new_sum(self.into(), rhs.into()) + } } impl ops::Add for Unknown { - type Output = Expr; - fn add(self, rhs: Unknown) -> Expr { - Expr::new_sum(self.into(), rhs.into()) - } + type Output = Expr; + fn add(self, rhs: Unknown) -> Expr { + Expr::new_sum(self.into(), rhs.into()) + } } impl ops::Sub for Unknown { - type Output = Expr; - fn sub(self, rhs: Expr) -> Expr { - Expr::new_minus(self.into(), rhs) - } + type Output = Expr; + fn sub(self, rhs: Expr) -> Expr { + Expr::new_minus(self.into(), rhs) + } } impl ops::Sub for Unknown { - type Output = Expr; - fn sub(self, rhs: Scalar) -> Expr { - Expr::new_minus(self.into(), rhs.into()) - } + type Output = Expr; + fn sub(self, rhs: Scalar) -> Expr { + Expr::new_minus(self.into(), rhs.into()) + } } impl ops::Sub for Unknown { - type Output = Expr; - fn sub(self, rhs: Unknown) -> Expr { - Expr::new_minus(self.into(), rhs.into()) - } + type Output = Expr; + fn sub(self, rhs: Unknown) -> Expr { + Expr::new_minus(self.into(), rhs.into()) + } } impl ops::Mul for Unknown { - type Output = Expr; - fn mul(self, rhs: Expr) -> Expr { - Expr::new_product(self.into(), rhs) - } + type Output = Expr; + fn mul(self, rhs: Expr) -> Expr { + Expr::new_product(self.into(), rhs) + } } impl ops::Mul for Unknown { - type Output = Expr; - fn mul(self, rhs: Scalar) -> Expr { - Expr::new_product(self.into(), rhs.into()) - } + type Output = Expr; + fn mul(self, rhs: Scalar) -> Expr { + Expr::new_product(self.into(), rhs.into()) + } } impl ops::Mul for Unknown { - type Output = Expr; - fn mul(self, rhs: Unknown) -> Expr { - Expr::new_product(self.into(), rhs.into()) - } + type Output = Expr; + fn mul(self, rhs: Unknown) -> Expr { + Expr::new_product(self.into(), rhs.into()) + } } impl ops::Div for Unknown { - type Output = Expr; - fn div(self, rhs: Expr) -> Expr { - Expr::new_div(self.into(), rhs) - } + type Output = Expr; + fn div(self, rhs: Expr) -> Expr { + Expr::new_div(self.into(), rhs) + } } impl ops::Div for Unknown { - type Output = Expr; - fn div(self, rhs: Scalar) -> Expr { - Expr::new_div(self.into(), rhs.into()) - } + type Output = Expr; + fn div(self, rhs: Scalar) -> Expr { + Expr::new_div(self.into(), rhs.into()) + } } impl ops::Div for Unknown { - type Output = Expr; - fn div(self, rhs: Unknown) -> Expr { - Expr::new_div(self.into(), rhs.into()) - } + type Output = Expr; + fn div(self, rhs: Unknown) -> Expr { + Expr::new_div(self.into(), rhs.into()) + } } impl ops::Neg for Unknown { - type Output = Expr; - fn neg(self) -> Expr { - Expr::new_neg(self.into()) - } + type Output = Expr; + fn neg(self) -> Expr { + Expr::new_neg(self.into()) + } } diff --git a/src/math/region.rs b/src/math/region.rs index 09a1cae..00ff31e 100644 --- a/src/math/region.rs +++ b/src/math/region.rs @@ -1,6 +1,6 @@ use std::fmt; -use super::{eqn, Value, Scalar, Expr, Point2, Rot2}; +use super::{eqn, Expr, Point2, Rot2, Scalar, Value}; // pub type Vec2 = nalgebra::Vector2; // pub type Point2 = nalgebra::Point2; @@ -39,7 +39,7 @@ impl fmt::Display for Region1 { Singleton(v) => write!(f, "{{ {} }}", v), Range(l, u) => write!(f, "[ {}, {} ]", l, u), Intersection(r1, r2) => write!(f, "{} ∩ {}", r1, r2), - Full => write!(f, "ℝ") + Full => write!(f, "ℝ"), } } } @@ -119,23 +119,20 @@ impl Region for Region1 { }, _ => None, }, - Intersection(r1, r2) => { - unimplemented!() - } - /*Union(r1, r2) => { - let distance = |a: Scalar, b: Scalar| (a - b).abs(); - match (r1.nearest(s), r2.nearest(s)) { - (None, None) => None, - (Some(n), None) | (None, Some(n)) => Some(n), - (Some(n1), Some(n2)) => Some({ - if distance(*s, n1) <= distance(*s, n2) { - n1 - } else { - n2 - } - }), - } - }*/ + Intersection(r1, r2) => unimplemented!(), /*Union(r1, r2) => { + let distance = |a: Scalar, b: Scalar| (a - b).abs(); + match (r1.nearest(s), r2.nearest(s)) { + (None, None) => None, + (Some(n), None) | (None, Some(n)) => Some(n), + (Some(n1), Some(n2)) => Some({ + if distance(*s, n1) <= distance(*s, n2) { + n1 + } else { + n2 + } + }), + } + }*/ } } } @@ -151,7 +148,11 @@ pub struct Line2 { impl fmt::Display for Line2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{{ = {} + {} * {} }}", self.start, self.dir, self.extent) + write!( + f, + "{{ = {} + {} * {} }}", + self.start, self.dir, self.extent + ) } } @@ -170,9 +171,13 @@ impl Line2 { _ => None, } } - + pub fn with_extent(self, new_extent: Region1) -> Line2 { - Line2 { start: self.start, dir: self.dir, extent: new_extent } + Line2 { + start: self.start, + dir: self.dir, + extent: new_extent, + } } pub fn nearest(&self, p: &Point2) -> Point2 { @@ -182,7 +187,7 @@ impl Line2 { match self.intersect(&perp) { Region2::Singleton(np) => np, Region2::Line(l) => l.evaluate_extent().expect("Line2::nearest not found"), - _ => panic!("Line2::nearest not found!") + _ => panic!("Line2::nearest not found!"), } } @@ -208,7 +213,8 @@ impl Line2 { b.dir.clone(), ); let (a_c, a_s, b_c, b_s) = (a_v.cos(), a_v.sin(), b_v.cos(), b_v.sin()); - let t_b = (a_0.x.clone() * a_s.clone() - a_0.y.clone() * a_c.clone() + let t_b = (a_0.x.clone() * a_s.clone() + - a_0.y.clone() * a_c.clone() - b_0.x.clone() * a_s.clone() + b_0.y.clone() * a_c.clone()) / (a_s.clone() * b_c.clone() - a_c.clone() * b_s.clone()); @@ -225,7 +231,11 @@ impl Line2 { dir: self.dir, extent: self.extent.simplify(), }; - trace!("line {}: simplify evaluate extent: {:?}", new_l, new_l.evaluate_extent()); + trace!( + "line {}: simplify evaluate extent: {:?}", + new_l, + new_l.evaluate_extent() + ); if let Some(p) = new_l.evaluate_extent() { return Region2::Singleton(p.simplify()); } @@ -261,7 +271,7 @@ impl fmt::Display for Region2 { Singleton(v) => write!(f, "{{ {} }}", v), Line(l) => l.fmt(f), Intersection(r1, r2) => write!(f, "{} ∩ {}", r1, r2), - Full => write!(f, "ℝ²") + Full => write!(f, "ℝ²"), } } } @@ -328,12 +338,11 @@ impl Region> for Region2 { (Const(cx), Const(cy)) => Some(Point2::new(cx, cy)), _ => None, } - } + } Intersection(r1, r2) => { None // r1.clone().intersect((**r2).clone()).nearest(p) - } - /*Union(r1, r2) => { + } /*Union(r1, r2) => { use nalgebra::distance; match (r1.nearest(p), r2.nearest(p)) { (None, None) => None, @@ -357,7 +366,8 @@ impl Region> for Region2 { } fn contains(&self, p: &Point2) -> Option { - self.nearest(p).map(|n| n.simplify() == p.clone().simplify()) + self.nearest(p) + .map(|n| n.simplify() == p.clone().simplify()) } fn nearest(&self, p: &Point2) -> Option> { @@ -367,23 +377,20 @@ impl Region> for Region2 { Full => Some(p.clone()), Singleton(n) => Some(n.clone()), Line(line) => Some(line.nearest(p)), - Intersection(r1, r2) => { - r1.clone().intersect((**r2).clone()).nearest(p) - } - /*Union(r1, r2) => { - use nalgebra::distance; - match (r1.nearest(p), r2.nearest(p)) { - (None, None) => None, - (Some(n), None) | (None, Some(n)) => Some(n), - (Some(n1), Some(n2)) => Some({ - if distance(p, &n1) <= distance(p, &n2) { - n1 - } else { - n2 - } - }), - } - }*/ + Intersection(r1, r2) => r1.clone().intersect((**r2).clone()).nearest(p), /*Union(r1, r2) => { + use nalgebra::distance; + match (r1.nearest(p), r2.nearest(p)) { + (None, None) => None, + (Some(n), None) | (None, Some(n)) => Some(n), + (Some(n1), Some(n2)) => Some({ + if distance(p, &n1) <= distance(p, &n2) { + n1 + } else { + n2 + } + }), + } + }*/ } } } @@ -419,9 +426,7 @@ impl Region2 { Region2::intersection(Singleton(n), o) } } - (Intersection(r1, r2), o) | (o, Intersection(r1, r2)) => { - r1.intersect(*r2).intersect(o) - } + (Intersection(r1, r2), o) | (o, Intersection(r1, r2)) => r1.intersect(*r2).intersect(o), (Line(l1), Line(l2)) => l1.intersect(&l2).simplify(), /*(Union(un1, un2), o) | (o, Union(un1, un2)) => { Self::union(un1.intersect(o), un2.intersect(o)) @@ -429,4 +434,4 @@ impl Region2 { (r1, r2) => Intersection(Box::new(r1), Box::new(r2)), } } -} \ No newline at end of file +} diff --git a/src/math/unknown.rs b/src/math/unknown.rs index 55a5f92..c741771 100644 --- a/src/math/unknown.rs +++ b/src/math/unknown.rs @@ -1,6 +1,6 @@ use std::collections::BTreeSet; -use std::iter::FromIterator; use std::fmt; +use std::iter::FromIterator; use super::Scalar; @@ -44,4 +44,4 @@ impl fmt::Display for Unknown { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "u{}", self.0) } -} \ No newline at end of file +} diff --git a/src/math/vec.rs b/src/math/vec.rs index 71c9f96..e5cc6d2 100644 --- a/src/math/vec.rs +++ b/src/math/vec.rs @@ -1,300 +1,303 @@ -use super::{Scalar, Value}; use super::eqn::Eqns; +use super::{Scalar, Value}; use std::ops; #[derive(Clone, PartialEq, Debug)] pub struct Vec2 { - pub x: T, - pub y: T, + pub x: T, + pub y: T, } impl Vec2 { - pub fn new(x: T, y: T) -> Self { - Self { x, y } - } + pub fn new(x: T, y: T) -> Self { + Self { x, y } + } } impl Vec2 { - pub fn normal2(self) -> Scalar { - self.x * self.x + self.y * self.y - } + pub fn normal2(self) -> Scalar { + self.x * self.x + self.y * self.y + } - pub fn normal(self) -> Scalar { - self.normal2().sqrt() - } + pub fn normal(self) -> Scalar { + self.normal2().sqrt() + } - pub fn normalize(self) -> Vec2 { - self.clone() / self.normal() - } + pub fn normalize(self) -> Vec2 { + self.clone() / self.normal() + } } impl Vec2 { - pub fn simplify(self) -> Self { - Self { - x: self.x.simplify(), - y: self.y.simplify(), + pub fn simplify(self) -> Self { + Self { + x: self.x.simplify(), + y: self.y.simplify(), + } } - } } impl, U> ops::Add> for Vec2 { - type Output = Vec2; - fn add(self, rhs: Vec2) -> Self::Output { - Self::Output { - x: self.x + rhs.x, - y: self.y + rhs.y, + type Output = Vec2; + fn add(self, rhs: Vec2) -> Self::Output { + Self::Output { + x: self.x + rhs.x, + y: self.y + rhs.y, + } } - } } impl, U> ops::Sub> for Vec2 { - type Output = Vec2; - fn sub(self, rhs: Vec2) -> Self::Output { - Self::Output { - x: self.x - rhs.x, - y: self.y - rhs.y, + type Output = Vec2; + fn sub(self, rhs: Vec2) -> Self::Output { + Self::Output { + x: self.x - rhs.x, + y: self.y - rhs.y, + } } - } } impl, U: Clone> ops::Mul for Vec2 { - type Output = Vec2; - fn mul(self, rhs: U) -> Self::Output { - Self::Output { - x: self.x * rhs.clone(), - y: self.y * rhs, + type Output = Vec2; + fn mul(self, rhs: U) -> Self::Output { + Self::Output { + x: self.x * rhs.clone(), + y: self.y * rhs, + } } - } } impl, U: Clone> ops::Div for Vec2 { - type Output = Vec2; - fn div(self, rhs: U) -> Self::Output { - Self::Output { - x: self.x / rhs.clone(), - y: self.y / rhs, + type Output = Vec2; + 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 { - pub x: T, - pub y: T, + pub x: T, + pub y: T, } impl Point2 { - pub fn new(x: T, y: T) -> Point2 { - Point2 { x, y } - } + pub fn new(x: T, y: T) -> Point2 { + Point2 { x, y } + } } impl Point2 { - pub fn simplify(self) -> Self { - Self { - x: self.x.distribute().simplify(), - y: self.y.distribute().simplify(), + pub fn simplify(self) -> Self { + Self { + x: self.x.distribute().simplify(), + y: self.y.distribute().simplify(), + } } - } - pub fn evaluate_with(self, eqns: &Eqns) -> Self { - Self { - x: self.x.evaluate_with(eqns), - y: self.y.evaluate_with(eqns), + pub fn evaluate_with(self, eqns: &Eqns) -> Self { + Self { + x: self.x.evaluate_with(eqns), + y: self.y.evaluate_with(eqns), + } } - } } impl From> for Point2 { - fn from(sp: Point2) -> Self { - Self { x: sp.x.into(), y: sp.y.into() } - } + fn from(sp: Point2) -> Self { + Self { + x: sp.x.into(), + y: sp.y.into(), + } + } } impl, U> ops::Add> for Point2 { - type Output = Point2; - fn add(self, rhs: Vec2) -> Self::Output { - Point2 { - x: self.x + rhs.x, - y: self.y + rhs.y, + type Output = Point2; + fn add(self, rhs: Vec2) -> Self::Output { + Point2 { + x: self.x + rhs.x, + y: self.y + rhs.y, + } } - } } impl, U> ops::Sub> for Point2 { - type Output = Point2; - fn sub(self, rhs: Vec2) -> Self::Output { - Point2 { - x: self.x - rhs.x, - y: self.y - rhs.y, + type Output = Point2; + fn sub(self, rhs: Vec2) -> Self::Output { + Point2 { + x: self.x - rhs.x, + y: self.y - rhs.y, + } } - } } impl, U> ops::Sub> for Point2 { - type Output = Vec2; - fn sub(self, rhs: Point2) -> Self::Output { - Vec2 { - x: self.x - rhs.x, - y: self.y - rhs.y, + type Output = Vec2; + fn sub(self, rhs: Point2) -> Self::Output { + Vec2 { + x: self.x - rhs.x, + y: self.y - rhs.y, + } } - } } use std::fmt; impl fmt::Display for Point2 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "<{}, {}>", self.x, self.y) - } + 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, + cos: Scalar, + sin: Scalar, } impl fmt::Display for Rot2 { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "<{}, {}>", self.cos, self.sin) - } + 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 up() -> Self { - Self { cos: 0., sin: 1. } - } - - pub fn right() -> Self { - Self { cos: 1., sin: 0. } - } - - 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 from_angle_deg(angle_deg: Scalar) -> Self { - Self::from_angle(angle_deg * std::f64::consts::PI / 180.) - } - - 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, - } - } - - pub fn dot(self, v: Vec2) -> Value { - v.x * self.cos + v.y * self.sin - } + pub fn from_cos_sin_unchecked(cos: Scalar, sin: Scalar) -> Self { + Self { cos, sin } + } + + pub fn up() -> Self { + Self { cos: 0., sin: 1. } + } + + pub fn right() -> Self { + Self { cos: 1., sin: 0. } + } + + 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 from_angle_deg(angle_deg: Scalar) -> Self { + Self::from_angle(angle_deg * std::f64::consts::PI / 180.) + } + + 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, + } + } + + pub fn dot(self, v: Vec2) -> Value { + v.x * self.cos + v.y * self.sin + } } impl From> for Rot2 { - fn from(v: Vec2) -> Rot2 { - let v = v.normalize(); - Rot2 { cos: v.x, sin: v.y } - } + fn from(v: Vec2) -> Rot2 { + let v = v.normalize(); + Rot2 { cos: v.x, sin: v.y } + } } impl ops::Mul for Rot2 { - type Output = Vec2; - fn mul(self, rhs: Scalar) -> Vec2 { - Vec2 { - x: self.cos * rhs, - y: self.sin * rhs, + type Output = Vec2; + fn mul(self, rhs: Scalar) -> Vec2 { + Vec2 { + x: self.cos * rhs, + y: self.sin * rhs, + } } - } } impl ops::Mul for Rot2 { - type Output = Vec2; - fn mul(self, rhs: Value) -> Vec2 { - Vec2 { - x: rhs.clone() * self.cos, - y: rhs * self.sin, + type Output = Vec2; + fn mul(self, rhs: Value) -> Vec2 { + Vec2 { + x: rhs.clone() * self.cos, + y: rhs * self.sin, + } } - } } impl ops::Add 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, + 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 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, + 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> for Rot2 { - type Output = Vec2; - fn mul(self, rhs: Vec2) -> Vec2 { - Vec2 { - x: self.cos * rhs.x - self.sin * rhs.y, - y: self.cos * rhs.y + self.sin * rhs.x, + type Output = Vec2; + fn mul(self, rhs: Vec2) -> Vec2 { + Vec2 { + x: self.cos * rhs.x - self.sin * rhs.y, + y: self.cos * rhs.y + self.sin * rhs.x, + } } - } } impl ops::Mul> for Rot2 { - type Output = Vec2; - fn mul(self, rhs: Vec2) -> Vec2 { - Vec2 { - x: rhs.x.clone() * self.cos - rhs.y.clone() * self.sin, - y: rhs.y * self.cos + rhs.x * self.sin, + type Output = Vec2; + fn mul(self, rhs: Vec2) -> Vec2 { + Vec2 { + x: rhs.x.clone() * self.cos - rhs.y.clone() * self.sin, + y: rhs.y * self.cos + rhs.x * self.sin, + } } - } } diff --git a/src/relation.rs b/src/relation.rs index 79de1e0..032167e 100644 --- a/src/relation.rs +++ b/src/relation.rs @@ -1,5 +1,5 @@ use crate::entity::{CPoint as PointEntity, PointRef}; -use crate::math::{Line2, Vec2, Point2, Region1, Region2, Rot2, Scalar, Value, GenericRegion}; +use crate::math::{GenericRegion, Line2, Point2, Region1, Region2, Rot2, Scalar, Value, Vec2}; #[derive(Clone, Copy, Debug, PartialEq)] pub enum ResolveResult { @@ -31,7 +31,12 @@ pub struct Coincident { impl Relation for Coincident { fn resolve(&self) -> ResolveResult { let (mut p1, mut p2) = (self.p1.borrow_mut(), self.p2.borrow_mut()); - let r = { p1.constraints().clone().intersect(p2.constraints().clone()).simplify() }; + let r = { + p1.constraints() + .clone() + .intersect(p2.constraints().clone()) + .simplify() + }; p1.reconstrain(r.clone()); p2.reconstrain(r.clone()); ResolveResult::from_r2(&r) @@ -50,11 +55,19 @@ impl PointAngle { } pub fn new_horizontal(p1: PointRef, p2: PointRef) -> Self { - Self::new(p1, p2, Rot2::from_cos_sin_unchecked((1.).into(), (0.).into())) + Self::new( + p1, + p2, + Rot2::from_cos_sin_unchecked((1.).into(), (0.).into()), + ) } pub fn new_vertical(p1: PointRef, p2: PointRef) -> Self { - Self::new(p1, p2, Rot2::from_cos_sin_unchecked((0.).into(), (1.).into())) + Self::new( + p1, + p2, + Rot2::from_cos_sin_unchecked((0.).into(), (1.).into()), + ) } } @@ -64,7 +77,11 @@ impl Relation for PointAngle { let (mut p1, mut p2) = (self.p1.borrow_mut(), self.p2.borrow_mut()); let constrain_line = |p1: &Point2, p2: &mut PointEntity| { let line = Region2::Line(Line2::new(p1.clone(), self.angle.clone(), Region1::Full)); - trace!("PointAngle line: {}, p2 constraint: {}", line, p2.constraints()); + trace!( + "PointAngle line: {}, p2 constraint: {}", + line, + p2.constraints() + ); let new_constraint = p2.constraints().clone().intersection(line).simplify(); trace!("PointAngle new_constraint: {}", new_constraint); p2.reconstrain(new_constraint); @@ -78,9 +95,9 @@ impl Relation for PointAngle { let r = self.angle.clone().conj() * (p2.clone() - p1.clone()); trace!("angle.cos: {}", r.x); // if relative_eq!(r.y, 0.) { - ResolveResult::Constrained + ResolveResult::Constrained // } else { - // ResolveResult::Overconstrained + // ResolveResult::Overconstrained // } } (Singleton(p), _) => constrain_line(p, &mut *p2), @@ -123,7 +140,11 @@ impl Relation for AlignedDistance { let constrain_line = |p1: Point2, p2: &mut PointEntity| { let angle = self.angle + Rot2::up(); let line = Region2::Line(Line2::new(p1.clone(), angle, Region1::Full)).simplify(); - trace!("AlignedDistance line: {}, p2 constraint: {}", line, p2.constraints()); + trace!( + "AlignedDistance line: {}, p2 constraint: {}", + line, + p2.constraints() + ); let new_constraint = p2.constraints().clone().intersection(line).simplify(); trace!("AlignedDistance new_constraint: {}", new_constraint); p2.reconstrain(new_constraint); @@ -136,9 +157,9 @@ impl Relation for AlignedDistance { let r = p2.clone() - p1.clone(); let d = self.angle.dot(r); // if relative_eq!(d, self.distance) { - ResolveResult::Constrained + ResolveResult::Constrained // } else { - // ResolveResult::Overconstrained + // ResolveResult::Overconstrained // } } (Singleton(pos), _) => constrain_line(pos.clone() + offset, &mut *p2),