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

18
src/main.rs

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

28
src/relation.rs

@ -1,4 +1,4 @@ @@ -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};
#[derive(Clone, Copy, Debug, PartialEq)]
@ -31,9 +31,9 @@ pub struct Coincident { @@ -31,9 +31,9 @@ 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.pos.constraints().clone().intersect(p2.pos.constraints().clone()).simplify() };
p1.pos.reconstrain(r.clone());
p2.pos.reconstrain(r.clone());
let r = { p1.constraints().clone().intersect(p2.constraints().clone()).simplify() };
p1.reconstrain(r.clone());
p2.reconstrain(r.clone());
ResolveResult::from_r2(&r)
}
}
@ -64,13 +64,13 @@ impl Relation for PointAngle { @@ -64,13 +64,13 @@ impl Relation for PointAngle {
let (mut p1, mut p2) = (self.p1.borrow_mut(), self.p2.borrow_mut());
let constrain_line = |p1: &Point2<Value>, p2: &mut PointEntity| {
let line = Region2::Line(Line2::new(p1.clone(), self.angle.clone(), Region1::Full));
trace!("PointAngle line: {}, p2 constraint: {}", line, p2.pos.constraints());
let new_constraint = p2.pos.constraints().clone().intersection(line).simplify();
trace!("PointAngle line: {}, p2 constraint: {}", line, p2.constraints());
let new_constraint = p2.constraints().clone().intersection(line).simplify();
trace!("PointAngle new_constraint: {}", new_constraint);
p2.pos.reconstrain(new_constraint);
ResolveResult::from_r2(p2.pos.constraints())
p2.reconstrain(new_constraint);
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,
(Singleton(p1), Singleton(p2)) => {
// if the angle p1 and p2 form is parallel to self.angle, the result
@ -123,14 +123,14 @@ impl Relation for AlignedDistance { @@ -123,14 +123,14 @@ impl Relation for AlignedDistance {
let constrain_line = |p1: Point2<Value>, 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.pos.constraints());
let new_constraint = p2.pos.constraints().clone().intersection(line).simplify();
trace!("AlignedDistance line: {}, p2 constraint: {}", line, p2.constraints());
let new_constraint = p2.constraints().clone().intersection(line).simplify();
trace!("AlignedDistance new_constraint: {}", new_constraint);
p2.pos.reconstrain(new_constraint);
ResolveResult::from_r2(p2.pos.constraints())
p2.reconstrain(new_constraint);
ResolveResult::from_r2(p2.constraints())
};
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,
(Singleton(p1), Singleton(p2)) => {
let r = p2.clone() - p1.clone();

Loading…
Cancel
Save