Browse Source

refactor out struct Point

eqn_relations
Alex Mikhalev 6 years ago
parent
commit
233c8eaad5
  1. 39
      src/entity.rs
  2. 18
      src/main.rs
  3. 28
      src/relation.rs

39
src/entity.rs

@ -5,21 +5,24 @@ use crate::math::{Point2, Region, Region1, Region2, Scalar};
use crate::math::eqn::{Eqns}; use crate::math::eqn::{Eqns};
use std::fmt; use std::fmt;
type EntityId = i64;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Var<T: Clone, TRegion: Region<T>> { pub struct Constrainable<T: Clone, TRegion: Region<T>> {
id: EntityId,
value: T, value: T,
constraints: TRegion, constraints: TRegion,
} }
impl<T: Clone + fmt::Display, TRegion: Region<T> + fmt::Display> fmt::Display for Var<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)
} }
} }
impl<T: Clone, TRegion: Region<T> + Clone> Var<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 { value, constraints } Self { id: 0, value, constraints }
} }
pub fn new_full(value: T) -> Self { pub fn new_full(value: T) -> Self {
@ -69,34 +72,22 @@ impl<T: Clone, TRegion: Region<T> + Clone> Var<T, TRegion> {
} }
} }
type ScalarVar = Var<Scalar, Region1>; pub type CScalar = Constrainable<Scalar, Region1>;
type PointVar = Var<Point2<Scalar>, Region2>; pub type CPoint = Constrainable<Point2<Scalar>, Region2>;
#[derive(Debug)]
pub struct Point {
// pub id: i64,
pub pos: PointVar,
}
pub type PointRef = Rc<RefCell<Point>>; pub type PointRef = Rc<RefCell<CPoint>>;
impl Point { impl CPoint {
pub fn new_ref(pos: PointVar) -> PointRef { pub fn into_ref(self) -> PointRef {
Rc::new(RefCell::new(Point { pos })) Rc::new(RefCell::new(self))
}
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Point {{ pos: {} }}", self.pos)
} }
} }
struct Line { struct Line {
p1: PointRef, p1: PointRef,
p2: PointRef, p2: PointRef,
len: ScalarVar, len: CScalar,
dir: ScalarVar, dir: CScalar,
} }
// struct System { // struct System {

18
src/main.rs

@ -17,7 +17,7 @@ mod math;
mod relation; mod relation;
fn main() { fn main() {
use entity::{Point, PointRef, Var}; use entity::{CPoint, PointRef};
use math::{Point2, eqn, Region2, Rot2}; use math::{Point2, eqn, Region2, Rot2};
use relation::{Relation, ResolveResult}; use relation::{Relation, ResolveResult};
@ -28,15 +28,15 @@ fn main() {
let u2 = math::eqn::Unknown(2); let u2 = math::eqn::Unknown(2);
// let u1 = eqn::Expr::from(1.); // let u1 = eqn::Expr::from(1.);
// let u2 = eqn::Expr::from(1.); // let u2 = eqn::Expr::from(1.);
let origin = Point::new_ref(Var::new_single(Point2::new((0.).into(), (0.).into()))); 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 = Point::new_ref(Var::new(Point2::new(1.,1.), Region2::Singleton(Point2::new((u1).into(), (u2).into())))); let p1 = CPoint::new(Point2::new(0.,0.), Region2::Singleton(Point2::new((u1).into(), (u2).into()))).into_ref();
let p2 = Point::new_ref(Var::new_full(Point2::new((4.).into(), (4.).into()))); let p2 = CPoint::new_full(Point2::new((4.).into(), (4.).into())).into_ref();
let p3 = Point::new_ref(Var::new_full(Point2::new((2.).into(), (2.).into()))); 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, p1, p2, p3:\n {}\n {}\n {}\n {}", "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(),
); );
}; };
@ -62,9 +62,9 @@ fn main() {
let rr = r.resolve(); let rr = r.resolve();
println!("resolve result: {:?}", rr); println!("resolve result: {:?}", rr);
print_points(&points); print_points(&points);
let mut pos = p2.borrow().pos.val().clone(); let mut pos = p2.borrow().val().clone();
println!("p2 pos: {}", pos); println!("p2 pos: {}", pos);
let mut pos = p3.borrow().pos.val().clone(); let mut pos = p3.borrow().val().clone();
println!("p3 pos: {}", pos); println!("p3 pos: {}", pos);
match rr { match rr {
ResolveResult::Underconstrained => { ResolveResult::Underconstrained => {
@ -94,7 +94,7 @@ fn main() {
let e2 = eqn::Eqn::new(eqn::Expr::Unkn(u2), eqn::Expr::Const(1.)); let e2 = eqn::Eqn::new(eqn::Expr::Unkn(u2), eqn::Expr::Const(1.));
let eqns = eqn::Eqns(vec![e1, e2]); let eqns = eqn::Eqns(vec![e1, e2]);
for p in &mut points { for p in &mut points {
p.borrow_mut().pos.resolve_with(&eqns); p.borrow_mut().resolve_with(&eqns);
} }
print_points(&points); print_points(&points);
} }

28
src/relation.rs

@ -1,4 +1,4 @@
use crate::entity::{Point 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::{Line2, Vec2, Point2, Region1, Region2, Rot2, Scalar, Value, GenericRegion};
#[derive(Clone, Copy, Debug, PartialEq)] #[derive(Clone, Copy, Debug, PartialEq)]
@ -31,9 +31,9 @@ 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.pos.constraints().clone().intersect(p2.pos.constraints().clone()).simplify() }; let r = { p1.constraints().clone().intersect(p2.constraints().clone()).simplify() };
p1.pos.reconstrain(r.clone()); p1.reconstrain(r.clone());
p2.pos.reconstrain(r.clone()); p2.reconstrain(r.clone());
ResolveResult::from_r2(&r) ResolveResult::from_r2(&r)
} }
} }
@ -64,13 +64,13 @@ 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.pos.constraints()); trace!("PointAngle line: {}, p2 constraint: {}", line, p2.constraints());
let new_constraint = p2.pos.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.pos.reconstrain(new_constraint); p2.reconstrain(new_constraint);
ResolveResult::from_r2(p2.pos.constraints()) ResolveResult::from_r2(p2.constraints())
}; };
match (&mut p1.pos.constraints(), &mut p2.pos.constraints()) { match (&mut p1.constraints(), &mut p2.constraints()) {
(Empty, _) | (_, Empty) => ResolveResult::Overconstrained, (Empty, _) | (_, Empty) => ResolveResult::Overconstrained,
(Singleton(p1), Singleton(p2)) => { (Singleton(p1), Singleton(p2)) => {
// if the angle p1 and p2 form is parallel to self.angle, the result // if the angle p1 and p2 form is parallel to self.angle, the result
@ -123,14 +123,14 @@ 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.pos.constraints()); trace!("AlignedDistance line: {}, p2 constraint: {}", line, p2.constraints());
let new_constraint = p2.pos.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.pos.reconstrain(new_constraint); p2.reconstrain(new_constraint);
ResolveResult::from_r2(p2.pos.constraints()) ResolveResult::from_r2(p2.constraints())
}; };
let offset: Vec2<Scalar> = self.angle * self.distance; let offset: Vec2<Scalar> = self.angle * self.distance;
match (&mut p1.pos.constraints(), &mut p2.pos.constraints()) { match (&mut p1.constraints(), &mut p2.constraints()) {
(Empty, _) | (_, Empty) => ResolveResult::Overconstrained, (Empty, _) | (_, Empty) => ResolveResult::Overconstrained,
(Singleton(p1), Singleton(p2)) => { (Singleton(p1), Singleton(p2)) => {
let r = p2.clone() - p1.clone(); let r = p2.clone() - p1.clone();

Loading…
Cancel
Save