Browse Source

cargo fmt

eqn_relations
Alex Mikhalev 6 years ago
parent
commit
3abe5c6573
  1. 12
      src/entity.rs
  2. 21
      src/main.rs
  3. 2
      src/math/eqn.rs
  4. 14
      src/math/expr.rs
  5. 5
      src/math/mod.rs
  6. 49
      src/math/region.rs
  7. 2
      src/math/unknown.rs
  8. 7
      src/math/vec.rs
  9. 33
      src/relation.rs

12
src/entity.rs

@ -1,8 +1,8 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use crate::math::eqn::Eqns;
use crate::math::{Point2, Region, Region1, Region2, Scalar}; use crate::math::{Point2, Region, Region1, Region2, Scalar};
use crate::math::eqn::{Eqns};
use std::fmt; use std::fmt;
type EntityId = i64; type EntityId = i64;
@ -14,7 +14,9 @@ pub struct Constrainable<T: Clone, TRegion: Region<T>> {
constraints: TRegion, constraints: TRegion,
} }
impl<T: Clone + fmt::Display, TRegion: Region<T> + fmt::Display> fmt::Display for Constrainable<T, TRegion> { impl<T: Clone + fmt::Display, TRegion: Region<T> + fmt::Display> fmt::Display
for Constrainable<T, TRegion>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{ {} ∈ {} }}", self.value, self.constraints) write!(f, "{{ {} ∈ {} }}", self.value, self.constraints)
} }
@ -22,7 +24,11 @@ impl<T: Clone + fmt::Display, TRegion: Region<T> + fmt::Display> fmt::Display fo
impl<T: Clone, TRegion: Region<T> + Clone> Constrainable<T, TRegion> { impl<T: Clone, TRegion: Region<T> + Clone> Constrainable<T, TRegion> {
pub fn new(value: T, constraints: TRegion) -> Self { 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 { pub fn new_full(value: T) -> Self {

21
src/main.rs

@ -18,7 +18,7 @@ mod relation;
fn main() { fn main() {
use entity::{CPoint, PointRef}; use entity::{CPoint, PointRef};
use math::{Point2, Expr, Region2, Rot2, Eqn, Eqns}; use math::{Eqn, Eqns, Expr, Point2, Region2, Rot2};
use relation::{Relation, ResolveResult}; use relation::{Relation, ResolveResult};
env_logger::init(); env_logger::init();
@ -30,14 +30,21 @@ fn main() {
// let u2 = eqn::Expr::from(1.); // let u2 = eqn::Expr::from(1.);
let origin = CPoint::new_single(Point2::new((0.).into(), (0.).into())).into_ref(); 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 = 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 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 p3 = CPoint::new_full(Point2::new((2.).into(), (2.).into())).into_ref();
let mut points: Vec<PointRef> = vec![origin.clone(), p1.clone(), p2.clone(), p3.clone()]; let mut points: Vec<PointRef> = vec![origin.clone(), p1.clone(), p2.clone(), p3.clone()];
let print_points = |points: &Vec<PointRef>| { let print_points = |points: &Vec<PointRef>| {
println!( println!(
"origin: {}\np1: {}\np2: {}\np3: {}", "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); print_points(&points);
@ -49,8 +56,12 @@ fn main() {
let c3 = relation::PointAngle::new_horizontal(p2.clone(), p3.clone()); let c3 = relation::PointAngle::new_horizontal(p2.clone(), p3.clone());
let c2 = relation::AlignedDistance::new_vertical(p1.clone(), p2.clone(), 12.); 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 c5 = relation::PointAngle::new(p1.clone(), p3.clone(), Rot2::from_angle_deg(0.572938698));
let mut relations: Vec<Box<dyn Relation>> = let mut relations: Vec<Box<dyn Relation>> = vec![
vec![/*Box::new(c1),*/ Box::new(c2), Box::new(c3), Box::new(c4), Box::new(c5)]; /*Box::new(c1),*/ Box::new(c2),
Box::new(c3),
Box::new(c4),
Box::new(c5),
];
let mut constrained: Vec<Box<dyn Relation>> = Vec::new(); let mut constrained: Vec<Box<dyn Relation>> = Vec::new();
let mut any_underconstrained = true; let mut any_underconstrained = true;
let mut any_constrained = true; let mut any_constrained = true;

2
src/math/eqn.rs

@ -1,8 +1,8 @@
use std::fmt; use std::fmt;
use super::Scalar;
use super::expr::Expr; use super::expr::Expr;
use super::unknown::*; use super::unknown::*;
use super::Scalar;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Eqn(pub Expr, pub Expr); pub struct Eqn(pub Expr, pub Expr);

14
src/math/expr.rs

@ -1,9 +1,9 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use super::Scalar;
use super::eqn::Eqns; use super::eqn::Eqns;
use super::unknown::{Unknown, Unknowns, UnknownSet}; use super::unknown::{Unknown, UnknownSet, Unknowns};
use super::Scalar;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum Expr { pub enum Expr {
@ -127,11 +127,11 @@ fn product_fold(l: Expr, r: Expr) -> Expr {
(Product(mut ls), Product(mut rs)) => { (Product(mut ls), Product(mut rs)) => {
ls.append(&mut rs); ls.append(&mut rs);
Product(ls) Product(ls)
}, }
(Product(mut ps), o) | (o, Product(mut ps)) => { (Product(mut ps), o) | (o, Product(mut ps)) => {
ps.push(o); ps.push(o);
Product(ps) Product(ps)
}, }
(l, r) => Expr::new_product(l, r), (l, r) => Expr::new_product(l, r),
} }
} }
@ -147,10 +147,8 @@ fn group_product(es: Exprs) -> Exprs {
Const(c) => match consts { Const(c) => match consts {
None => consts = Some(c), None => consts = Some(c),
Some(cs) => consts = Some(c * cs), Some(cs) => consts = Some(c * cs),
} },
e => { e => other.push(e),
other.push(e)
}
} }
} }
if let Some(cs) = consts { if let Some(cs) = consts {

5
src/math/mod.rs

@ -1,4 +1,3 @@
pub mod eqn; pub mod eqn;
pub mod expr; pub mod expr;
pub mod ops; pub mod ops;
@ -8,9 +7,9 @@ pub mod vec;
pub use eqn::{Eqn, Eqns}; pub use eqn::{Eqn, Eqns};
pub use expr::{Expr, Exprs}; pub use expr::{Expr, Exprs};
pub use unknown::{Unknown, Unknowns, UnknownSet};
pub use region::{Region, Region1, Line2, Region2, GenericRegion};
pub use ops::*; pub use ops::*;
pub use region::{GenericRegion, Line2, Region, Region1, Region2};
pub use unknown::{Unknown, UnknownSet, Unknowns};
pub use vec::*; pub use vec::*;
pub type Scalar = f64; pub type Scalar = f64;

49
src/math/region.rs

@ -1,6 +1,6 @@
use std::fmt; use std::fmt;
use super::{eqn, Value, Scalar, Expr, Point2, Rot2}; use super::{eqn, Expr, Point2, Rot2, Scalar, Value};
// pub type Vec2 = nalgebra::Vector2<Value>; // pub type Vec2 = nalgebra::Vector2<Value>;
// pub type Point2 = nalgebra::Point2<Value>; // pub type Point2 = nalgebra::Point2<Value>;
@ -39,7 +39,7 @@ impl fmt::Display for Region1 {
Singleton(v) => write!(f, "{{ {} }}", v), Singleton(v) => write!(f, "{{ {} }}", v),
Range(l, u) => write!(f, "[ {}, {} ]", l, u), Range(l, u) => write!(f, "[ {}, {} ]", l, u),
Intersection(r1, r2) => write!(f, "{} ∩ {}", r1, r2), Intersection(r1, r2) => write!(f, "{} ∩ {}", r1, r2),
Full => write!(f, "ℝ") Full => write!(f, "ℝ"),
} }
} }
} }
@ -119,10 +119,7 @@ impl Region<Scalar> for Region1 {
}, },
_ => None, _ => None,
}, },
Intersection(r1, r2) => { Intersection(r1, r2) => unimplemented!(), /*Union(r1, r2) => {
unimplemented!()
}
/*Union(r1, r2) => {
let distance = |a: Scalar, b: Scalar| (a - b).abs(); let distance = |a: Scalar, b: Scalar| (a - b).abs();
match (r1.nearest(s), r2.nearest(s)) { match (r1.nearest(s), r2.nearest(s)) {
(None, None) => None, (None, None) => None,
@ -151,7 +148,11 @@ pub struct Line2 {
impl fmt::Display for Line2 { impl fmt::Display for Line2 {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{{ <x, y> = {} + {} * {} }}", self.start, self.dir, self.extent) write!(
f,
"{{ <x, y> = {} + {} * {} }}",
self.start, self.dir, self.extent
)
} }
} }
@ -172,7 +173,11 @@ impl Line2 {
} }
pub fn with_extent(self, new_extent: Region1) -> Line2 { 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<Value>) -> Point2<Value> { pub fn nearest(&self, p: &Point2<Value>) -> Point2<Value> {
@ -182,7 +187,7 @@ impl Line2 {
match self.intersect(&perp) { match self.intersect(&perp) {
Region2::Singleton(np) => np, Region2::Singleton(np) => np,
Region2::Line(l) => l.evaluate_extent().expect("Line2::nearest not found"), 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(), 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 (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.x.clone() * a_s.clone()
+ b_0.y.clone() * a_c.clone()) + b_0.y.clone() * a_c.clone())
/ (a_s.clone() * b_c.clone() - a_c.clone() * b_s.clone()); / (a_s.clone() * b_c.clone() - a_c.clone() * b_s.clone());
@ -225,7 +231,11 @@ impl Line2 {
dir: self.dir, dir: self.dir,
extent: self.extent.simplify(), 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() { if let Some(p) = new_l.evaluate_extent() {
return Region2::Singleton(p.simplify()); return Region2::Singleton(p.simplify());
} }
@ -261,7 +271,7 @@ impl fmt::Display for Region2 {
Singleton(v) => write!(f, "{{ {} }}", v), Singleton(v) => write!(f, "{{ {} }}", v),
Line(l) => l.fmt(f), Line(l) => l.fmt(f),
Intersection(r1, r2) => write!(f, "{} ∩ {}", r1, r2), Intersection(r1, r2) => write!(f, "{} ∩ {}", r1, r2),
Full => write!(f, "ℝ²") Full => write!(f, "ℝ²"),
} }
} }
} }
@ -332,8 +342,7 @@ impl Region<Point2<Scalar>> for Region2 {
Intersection(r1, r2) => { Intersection(r1, r2) => {
None None
// r1.clone().intersect((**r2).clone()).nearest(p) // r1.clone().intersect((**r2).clone()).nearest(p)
} } /*Union(r1, r2) => {
/*Union(r1, r2) => {
use nalgebra::distance; use nalgebra::distance;
match (r1.nearest(p), r2.nearest(p)) { match (r1.nearest(p), r2.nearest(p)) {
(None, None) => None, (None, None) => None,
@ -357,7 +366,8 @@ impl Region<Point2<Value>> for Region2 {
} }
fn contains(&self, p: &Point2<Value>) -> Option<bool> { fn contains(&self, p: &Point2<Value>) -> Option<bool> {
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<Value>) -> Option<Point2<Value>> { fn nearest(&self, p: &Point2<Value>) -> Option<Point2<Value>> {
@ -367,10 +377,7 @@ impl Region<Point2<Value>> for Region2 {
Full => Some(p.clone()), Full => Some(p.clone()),
Singleton(n) => Some(n.clone()), Singleton(n) => Some(n.clone()),
Line(line) => Some(line.nearest(p)), Line(line) => Some(line.nearest(p)),
Intersection(r1, r2) => { Intersection(r1, r2) => r1.clone().intersect((**r2).clone()).nearest(p), /*Union(r1, r2) => {
r1.clone().intersect((**r2).clone()).nearest(p)
}
/*Union(r1, r2) => {
use nalgebra::distance; use nalgebra::distance;
match (r1.nearest(p), r2.nearest(p)) { match (r1.nearest(p), r2.nearest(p)) {
(None, None) => None, (None, None) => None,
@ -419,9 +426,7 @@ impl Region2 {
Region2::intersection(Singleton(n), o) Region2::intersection(Singleton(n), o)
} }
} }
(Intersection(r1, r2), o) | (o, Intersection(r1, r2)) => { (Intersection(r1, r2), o) | (o, Intersection(r1, r2)) => r1.intersect(*r2).intersect(o),
r1.intersect(*r2).intersect(o)
}
(Line(l1), Line(l2)) => l1.intersect(&l2).simplify(), (Line(l1), Line(l2)) => l1.intersect(&l2).simplify(),
/*(Union(un1, un2), o) | (o, Union(un1, un2)) => { /*(Union(un1, un2), o) | (o, Union(un1, un2)) => {
Self::union(un1.intersect(o), un2.intersect(o)) Self::union(un1.intersect(o), un2.intersect(o))

2
src/math/unknown.rs

@ -1,6 +1,6 @@
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::iter::FromIterator;
use std::fmt; use std::fmt;
use std::iter::FromIterator;
use super::Scalar; use super::Scalar;

7
src/math/vec.rs

@ -1,5 +1,5 @@
use super::{Scalar, Value};
use super::eqn::Eqns; use super::eqn::Eqns;
use super::{Scalar, Value};
use std::ops; use std::ops;
@ -108,7 +108,10 @@ impl Point2<Value> {
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(),
}
} }
} }

33
src/relation.rs

@ -1,5 +1,5 @@
use crate::entity::{CPoint as PointEntity, PointRef}; 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)] #[derive(Clone, Copy, Debug, PartialEq)]
pub enum ResolveResult { pub enum ResolveResult {
@ -31,7 +31,12 @@ pub struct Coincident {
impl Relation for Coincident { impl Relation for Coincident {
fn resolve(&self) -> ResolveResult { fn resolve(&self) -> ResolveResult {
let (mut p1, mut p2) = (self.p1.borrow_mut(), self.p2.borrow_mut()); 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()); p1.reconstrain(r.clone());
p2.reconstrain(r.clone()); p2.reconstrain(r.clone());
ResolveResult::from_r2(&r) ResolveResult::from_r2(&r)
@ -50,11 +55,19 @@ impl PointAngle {
} }
pub fn new_horizontal(p1: PointRef, p2: PointRef) -> Self { 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 { 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 (mut p1, mut p2) = (self.p1.borrow_mut(), self.p2.borrow_mut());
let constrain_line = |p1: &Point2<Value>, p2: &mut PointEntity| { let constrain_line = |p1: &Point2<Value>, p2: &mut PointEntity| {
let line = Region2::Line(Line2::new(p1.clone(), self.angle.clone(), Region1::Full)); 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(); let new_constraint = p2.constraints().clone().intersection(line).simplify();
trace!("PointAngle new_constraint: {}", new_constraint); trace!("PointAngle new_constraint: {}", new_constraint);
p2.reconstrain(new_constraint); p2.reconstrain(new_constraint);
@ -123,7 +140,11 @@ impl Relation for AlignedDistance {
let constrain_line = |p1: Point2<Value>, p2: &mut PointEntity| { let constrain_line = |p1: Point2<Value>, p2: &mut PointEntity| {
let angle = self.angle + Rot2::up(); let angle = self.angle + Rot2::up();
let line = Region2::Line(Line2::new(p1.clone(), angle, Region1::Full)).simplify(); 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(); let new_constraint = p2.constraints().clone().intersection(line).simplify();
trace!("AlignedDistance new_constraint: {}", new_constraint); trace!("AlignedDistance new_constraint: {}", new_constraint);
p2.reconstrain(new_constraint); p2.reconstrain(new_constraint);

Loading…
Cancel
Save