allow substitution of variables
This commit is contained in:
parent
8da067fec2
commit
157535b5ff
@ -2,6 +2,7 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use crate::math::{Point2, Region, Region1, Region2, Scalar};
|
||||
use crate::math::eqn::{Eqns};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@ -16,7 +17,7 @@ impl<T: Clone + fmt::Display, TRegion: Region<T> + fmt::Display> fmt::Display fo
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone, TRegion: Region<T>> Var<T, TRegion> {
|
||||
impl<T: Clone, TRegion: Region<T> + Clone> Var<T, TRegion> {
|
||||
pub fn new(value: T, constraints: TRegion) -> Self {
|
||||
Self { value, constraints }
|
||||
}
|
||||
@ -33,6 +34,16 @@ impl<T: Clone, TRegion: Region<T>> Var<T, TRegion> {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn evaluate_with(&mut self, eqns: &Eqns) -> bool {
|
||||
self.constraints = self.constraints.clone().evaluate_with(eqns).simplify();
|
||||
if let Some(n) = self.constraints.nearest(&self.value) {
|
||||
self.value = n;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn constraints(&self) -> &TRegion {
|
||||
&self.constraints
|
||||
}
|
||||
|
@ -90,4 +90,11 @@ fn main() {
|
||||
} else {
|
||||
println!("All constraints have been solved")
|
||||
}
|
||||
let e1 = eqn::Eqn::new(eqn::Expr::Unkn(u1), eqn::Expr::Const(1.));
|
||||
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.evaluate_with(&eqns);
|
||||
}
|
||||
print_points(&points);
|
||||
}
|
||||
|
@ -588,7 +588,7 @@ impl fmt::Display for Eqn {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Eqns(Vec<Eqn>);
|
||||
pub struct Eqns(pub Vec<Eqn>);
|
||||
|
||||
impl Unknowns for Eqns {
|
||||
fn unknowns(&self) -> UnknownSet {
|
||||
|
@ -21,10 +21,15 @@ pub type Value = eqn::Expr;
|
||||
|
||||
// pub type Rot2 = nalgebra::UnitComplex<Value>;
|
||||
|
||||
pub trait Region<T> {
|
||||
pub trait GenericRegion {
|
||||
fn full() -> Self;
|
||||
fn intersection(self, other: Self) -> Self;
|
||||
fn simplify(self) -> Self;
|
||||
fn evaluate_with(self, eqns: &eqn::Eqns) -> Self;
|
||||
}
|
||||
|
||||
pub trait Region<T>: GenericRegion {
|
||||
fn singleton(value: T) -> Self;
|
||||
// fn intersection(self, other: Self) -> Self;
|
||||
|
||||
fn nearest(&self, value: &T) -> Option<T>;
|
||||
fn contains(&self, value: &T) -> Option<bool>;
|
||||
@ -53,12 +58,16 @@ impl fmt::Display for Region1 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Region1 {
|
||||
pub fn intersection(self, other: Region1) -> Self {
|
||||
impl GenericRegion for Region1 {
|
||||
fn intersection(self, other: Region1) -> Self {
|
||||
Region1::Intersection(Box::new(self), Box::new(other))
|
||||
}
|
||||
|
||||
pub fn simplify(self) -> Self {
|
||||
fn full() -> Self {
|
||||
Region1::Full
|
||||
}
|
||||
|
||||
fn simplify(self) -> Self {
|
||||
use Region1::*;
|
||||
match self {
|
||||
Singleton(n) => Singleton(n.simplify()),
|
||||
@ -67,13 +76,19 @@ impl Region1 {
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_with(self, eqns: &eqn::Eqns) -> Self {
|
||||
use Region1::*;
|
||||
match self {
|
||||
Singleton(n) => Singleton(n.evaluate_with(eqns)),
|
||||
Range(l, u) => Range(l.evaluate_with(eqns), u.evaluate_with(eqns)),
|
||||
Intersection(r1, r2) => r1.evaluate_with(eqns).intersection(r2.evaluate_with(eqns)),
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Region<Scalar> for Region1 {
|
||||
fn full() -> Self {
|
||||
Region1::Full
|
||||
}
|
||||
|
||||
fn singleton(value: Scalar) -> Self {
|
||||
Region1::Singleton(value.into())
|
||||
}
|
||||
@ -230,6 +245,14 @@ impl Line2 {
|
||||
}
|
||||
Region2::Line(new_l)
|
||||
}
|
||||
|
||||
pub fn evaluate_with(self, eqns: &eqn::Eqns) -> Self {
|
||||
Line2 {
|
||||
start: self.start.evaluate_with(eqns),
|
||||
dir: self.dir,
|
||||
extent: self.extent.evaluate_with(eqns),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -257,11 +280,42 @@ impl fmt::Display for Region2 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Region<Point2<Scalar>> for Region2 {
|
||||
impl GenericRegion for Region2 {
|
||||
fn full() -> Self {
|
||||
Region2::Full
|
||||
}
|
||||
|
||||
fn intersection(self, other: Self) -> Self {
|
||||
use Region2::*;
|
||||
match (self, other) {
|
||||
(Empty, _) | (_, Empty) => Empty,
|
||||
(Full, r) | (r, Full) => r,
|
||||
(r1, r2) => Intersection(Box::new(r1), Box::new(r2)),
|
||||
}
|
||||
}
|
||||
|
||||
fn simplify(self) -> Region2 {
|
||||
use Region2::*;
|
||||
match self {
|
||||
Singleton(n) => Singleton(n.simplify()),
|
||||
Line(l) => l.simplify(),
|
||||
Intersection(r1, r2) => r1.simplify().intersect(r2.simplify()),
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate_with(self, eqns: &eqn::Eqns) -> Self {
|
||||
use Region2::*;
|
||||
match self {
|
||||
Singleton(n) => Singleton(n.evaluate_with(eqns)),
|
||||
Line(l) => Line(l.evaluate_with(eqns)),
|
||||
Intersection(r1, r2) => r1.evaluate_with(eqns).intersection(r2.evaluate_with(eqns)),
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Region<Point2<Scalar>> for Region2 {
|
||||
fn singleton(value: Point2<Scalar>) -> Self {
|
||||
Region2::Singleton(value.into())
|
||||
}
|
||||
@ -312,10 +366,6 @@ impl Region<Point2<Scalar>> for Region2 {
|
||||
}
|
||||
|
||||
impl Region<Point2<Value>> for Region2 {
|
||||
fn full() -> Self {
|
||||
Region2::Full
|
||||
}
|
||||
|
||||
fn singleton(value: Point2<Value>) -> Self {
|
||||
Region2::Singleton(value)
|
||||
}
|
||||
@ -353,15 +403,6 @@ impl Region<Point2<Value>> for Region2 {
|
||||
}
|
||||
|
||||
impl Region2 {
|
||||
pub fn intersection(self, other: Self) -> Self {
|
||||
use Region2::*;
|
||||
match (self, other) {
|
||||
(Empty, _) | (_, Empty) => Empty,
|
||||
(Full, r) | (r, Full) => r,
|
||||
(r1, r2) => Intersection(Box::new(r1), Box::new(r2)),
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn union(r1: Region2, r2: Region2) -> Region2 {
|
||||
use Region2::*;
|
||||
@ -402,14 +443,4 @@ impl Region2 {
|
||||
(r1, r2) => Intersection(Box::new(r1), Box::new(r2)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn simplify(self) -> Region2 {
|
||||
use Region2::*;
|
||||
match self {
|
||||
Singleton(n) => Singleton(n.simplify()),
|
||||
Line(l) => l.simplify(),
|
||||
Intersection(r1, r2) => r1.simplify().intersect(r2.simplify()),
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use super::{Scalar, Value};
|
||||
use super::eqn::Eqns;
|
||||
|
||||
use std::ops;
|
||||
|
||||
@ -92,8 +93,15 @@ impl<T> Point2<T> {
|
||||
impl Point2<Value> {
|
||||
pub fn simplify(self) -> Self {
|
||||
Self {
|
||||
x: self.x.distribute().simplify().distribute().simplify(),
|
||||
y: self.y.distribute().simplify().distribute().simplify(),
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::entity::{Point as PointEntity, PointRef};
|
||||
use crate::math::{Line2, Vec2, Point2, Region1, Region2, Rot2, Scalar, Value, Region};
|
||||
use crate::math::{Line2, Vec2, Point2, Region1, Region2, Rot2, Scalar, Value, GenericRegion};
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub enum ResolveResult {
|
||||
|
Loading…
x
Reference in New Issue
Block a user