refactor out struct Point
This commit is contained in:
parent
461088da3a
commit
233c8eaad5
@ -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 type PointRef = Rc<RefCell<CPoint>>;
|
||||||
pub struct Point {
|
|
||||||
// pub id: i64,
|
|
||||||
pub pos: PointVar,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type PointRef = Rc<RefCell<Point>>;
|
impl CPoint {
|
||||||
|
pub fn into_ref(self) -> PointRef {
|
||||||
impl Point {
|
Rc::new(RefCell::new(self))
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
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);
|
||||||
}
|
}
|
||||||
|
@ -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…
x
Reference in New Issue
Block a user