cargo fmt
This commit is contained in:
parent
a6c4906773
commit
3abe5c6573
@ -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
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;
|
||||||
|
@ -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);
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,22 +143,20 @@ fn group_product(es: Exprs) -> Exprs {
|
|||||||
let mut other = Exprs::new();
|
let mut other = Exprs::new();
|
||||||
for e in es {
|
for e in es {
|
||||||
let unkns = e.unknowns();
|
let unkns = e.unknowns();
|
||||||
match e {
|
match e {
|
||||||
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 {
|
||||||
if relative_eq!(cs, 0.0) {
|
if relative_eq!(cs, 0.0) {
|
||||||
other.clear();
|
other.clear();
|
||||||
other.push(Const(0.0))
|
other.push(Const(0.0))
|
||||||
} else if relative_ne!(cs, 1.0) {
|
} else if relative_ne!(cs, 1.0) {
|
||||||
other.push(Const(cs))
|
other.push(Const(cs))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
trace!("group product: {:?} => {:?}", es2, other);
|
trace!("group product: {:?} => {:?}", es2, other);
|
||||||
@ -457,4 +455,4 @@ impl fmt::Display for Expr {
|
|||||||
Neg(e) => write!(f, "-({})", e),
|
Neg(e) => write!(f, "-({})", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
220
src/math/ops.rs
220
src/math/ops.rs
@ -3,195 +3,195 @@ use std::ops;
|
|||||||
use super::{Expr, Scalar, Unknown};
|
use super::{Expr, Scalar, Unknown};
|
||||||
|
|
||||||
impl From<Scalar> for Expr {
|
impl From<Scalar> for Expr {
|
||||||
fn from(c: Scalar) -> Expr {
|
fn from(c: Scalar) -> Expr {
|
||||||
Expr::Const(c)
|
Expr::Const(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Unknown> for Expr {
|
impl From<Unknown> for Expr {
|
||||||
fn from(u: Unknown) -> Expr {
|
fn from(u: Unknown) -> Expr {
|
||||||
Expr::Unkn(u)
|
Expr::Unkn(u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Expr> for Expr {
|
impl ops::Add<Expr> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn add(self, rhs: Expr) -> Expr {
|
fn add(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_sum(self, rhs)
|
Expr::new_sum(self, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Scalar> for Expr {
|
impl ops::Add<Scalar> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn add(self, rhs: Scalar) -> Expr {
|
fn add(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_sum(self, rhs.into())
|
Expr::new_sum(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Unknown> for Expr {
|
impl ops::Add<Unknown> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn add(self, rhs: Unknown) -> Expr {
|
fn add(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_sum(self, rhs.into())
|
Expr::new_sum(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Expr> for Expr {
|
impl ops::Sub<Expr> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn sub(self, rhs: Expr) -> Expr {
|
fn sub(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_minus(self, rhs)
|
Expr::new_minus(self, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Scalar> for Expr {
|
impl ops::Sub<Scalar> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn sub(self, rhs: Scalar) -> Expr {
|
fn sub(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_minus(self, rhs.into())
|
Expr::new_minus(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Unknown> for Expr {
|
impl ops::Sub<Unknown> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn sub(self, rhs: Unknown) -> Expr {
|
fn sub(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_minus(self, rhs.into())
|
Expr::new_minus(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Expr> for Expr {
|
impl ops::Mul<Expr> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn mul(self, rhs: Expr) -> Expr {
|
fn mul(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_product(self, rhs)
|
Expr::new_product(self, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Scalar> for Expr {
|
impl ops::Mul<Scalar> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn mul(self, rhs: Scalar) -> Expr {
|
fn mul(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_product(self, rhs.into())
|
Expr::new_product(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Unknown> for Expr {
|
impl ops::Mul<Unknown> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn mul(self, rhs: Unknown) -> Expr {
|
fn mul(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_product(self, rhs.into())
|
Expr::new_product(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<Expr> for Expr {
|
impl ops::Div<Expr> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn div(self, rhs: Expr) -> Expr {
|
fn div(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_div(self, rhs)
|
Expr::new_div(self, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<Scalar> for Expr {
|
impl ops::Div<Scalar> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn div(self, rhs: Scalar) -> Expr {
|
fn div(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_div(self, rhs.into())
|
Expr::new_div(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<Unknown> for Expr {
|
impl ops::Div<Unknown> for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn div(self, rhs: Unknown) -> Expr {
|
fn div(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_div(self, rhs.into())
|
Expr::new_div(self, rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Neg for Expr {
|
impl ops::Neg for Expr {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn neg(self) -> Expr {
|
fn neg(self) -> Expr {
|
||||||
Expr::new_neg(self)
|
Expr::new_neg(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Expr> for Unknown {
|
impl ops::Add<Expr> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn add(self, rhs: Expr) -> Expr {
|
fn add(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_sum(self.into(), rhs)
|
Expr::new_sum(self.into(), rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Scalar> for Unknown {
|
impl ops::Add<Scalar> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn add(self, rhs: Scalar) -> Expr {
|
fn add(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_sum(self.into(), rhs.into())
|
Expr::new_sum(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Unknown> for Unknown {
|
impl ops::Add<Unknown> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn add(self, rhs: Unknown) -> Expr {
|
fn add(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_sum(self.into(), rhs.into())
|
Expr::new_sum(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Expr> for Unknown {
|
impl ops::Sub<Expr> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn sub(self, rhs: Expr) -> Expr {
|
fn sub(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_minus(self.into(), rhs)
|
Expr::new_minus(self.into(), rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Scalar> for Unknown {
|
impl ops::Sub<Scalar> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn sub(self, rhs: Scalar) -> Expr {
|
fn sub(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_minus(self.into(), rhs.into())
|
Expr::new_minus(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Unknown> for Unknown {
|
impl ops::Sub<Unknown> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn sub(self, rhs: Unknown) -> Expr {
|
fn sub(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_minus(self.into(), rhs.into())
|
Expr::new_minus(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Expr> for Unknown {
|
impl ops::Mul<Expr> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn mul(self, rhs: Expr) -> Expr {
|
fn mul(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_product(self.into(), rhs)
|
Expr::new_product(self.into(), rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Scalar> for Unknown {
|
impl ops::Mul<Scalar> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn mul(self, rhs: Scalar) -> Expr {
|
fn mul(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_product(self.into(), rhs.into())
|
Expr::new_product(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Unknown> for Unknown {
|
impl ops::Mul<Unknown> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn mul(self, rhs: Unknown) -> Expr {
|
fn mul(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_product(self.into(), rhs.into())
|
Expr::new_product(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<Expr> for Unknown {
|
impl ops::Div<Expr> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn div(self, rhs: Expr) -> Expr {
|
fn div(self, rhs: Expr) -> Expr {
|
||||||
Expr::new_div(self.into(), rhs)
|
Expr::new_div(self.into(), rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<Scalar> for Unknown {
|
impl ops::Div<Scalar> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn div(self, rhs: Scalar) -> Expr {
|
fn div(self, rhs: Scalar) -> Expr {
|
||||||
Expr::new_div(self.into(), rhs.into())
|
Expr::new_div(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Div<Unknown> for Unknown {
|
impl ops::Div<Unknown> for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn div(self, rhs: Unknown) -> Expr {
|
fn div(self, rhs: Unknown) -> Expr {
|
||||||
Expr::new_div(self.into(), rhs.into())
|
Expr::new_div(self.into(), rhs.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Neg for Unknown {
|
impl ops::Neg for Unknown {
|
||||||
type Output = Expr;
|
type Output = Expr;
|
||||||
fn neg(self) -> Expr {
|
fn neg(self) -> Expr {
|
||||||
Expr::new_neg(self.into())
|
Expr::new_neg(self.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,23 +119,20 @@ impl Region<Scalar> for Region1 {
|
|||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Intersection(r1, r2) => {
|
Intersection(r1, r2) => unimplemented!(), /*Union(r1, r2) => {
|
||||||
unimplemented!()
|
let distance = |a: Scalar, b: Scalar| (a - b).abs();
|
||||||
}
|
match (r1.nearest(s), r2.nearest(s)) {
|
||||||
/*Union(r1, r2) => {
|
(None, None) => None,
|
||||||
let distance = |a: Scalar, b: Scalar| (a - b).abs();
|
(Some(n), None) | (None, Some(n)) => Some(n),
|
||||||
match (r1.nearest(s), r2.nearest(s)) {
|
(Some(n1), Some(n2)) => Some({
|
||||||
(None, None) => None,
|
if distance(*s, n1) <= distance(*s, n2) {
|
||||||
(Some(n), None) | (None, Some(n)) => Some(n),
|
n1
|
||||||
(Some(n1), Some(n2)) => Some({
|
} else {
|
||||||
if distance(*s, n1) <= distance(*s, n2) {
|
n2
|
||||||
n1
|
}
|
||||||
} else {
|
}),
|
||||||
n2
|
}
|
||||||
}
|
}*/
|
||||||
}),
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,9 +171,13 @@ impl Line2 {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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, "ℝ²"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,12 +338,11 @@ impl Region<Point2<Scalar>> for Region2 {
|
|||||||
(Const(cx), Const(cy)) => Some(Point2::new(cx, cy)),
|
(Const(cx), Const(cy)) => Some(Point2::new(cx, cy)),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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,23 +377,20 @@ 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)
|
use nalgebra::distance;
|
||||||
}
|
match (r1.nearest(p), r2.nearest(p)) {
|
||||||
/*Union(r1, r2) => {
|
(None, None) => None,
|
||||||
use nalgebra::distance;
|
(Some(n), None) | (None, Some(n)) => Some(n),
|
||||||
match (r1.nearest(p), r2.nearest(p)) {
|
(Some(n1), Some(n2)) => Some({
|
||||||
(None, None) => None,
|
if distance(p, &n1) <= distance(p, &n2) {
|
||||||
(Some(n), None) | (None, Some(n)) => Some(n),
|
n1
|
||||||
(Some(n1), Some(n2)) => Some({
|
} else {
|
||||||
if distance(p, &n1) <= distance(p, &n2) {
|
n2
|
||||||
n1
|
}
|
||||||
} else {
|
}),
|
||||||
n2
|
}
|
||||||
}
|
}*/
|
||||||
}),
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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))
|
||||||
@ -429,4 +434,4 @@ impl Region2 {
|
|||||||
(r1, r2) => Intersection(Box::new(r1), Box::new(r2)),
|
(r1, r2) => Intersection(Box::new(r1), Box::new(r2)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
@ -44,4 +44,4 @@ impl fmt::Display for Unknown {
|
|||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "u{}", self.0)
|
write!(f, "u{}", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
381
src/math/vec.rs
381
src/math/vec.rs
@ -1,300 +1,303 @@
|
|||||||
use super::{Scalar, Value};
|
|
||||||
use super::eqn::Eqns;
|
use super::eqn::Eqns;
|
||||||
|
use super::{Scalar, Value};
|
||||||
|
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct Vec2<T> {
|
pub struct Vec2<T> {
|
||||||
pub x: T,
|
pub x: T,
|
||||||
pub y: T,
|
pub y: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Vec2<T> {
|
impl<T> Vec2<T> {
|
||||||
pub fn new(x: T, y: T) -> Self {
|
pub fn new(x: T, y: T) -> Self {
|
||||||
Self { x, y }
|
Self { x, y }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vec2<Scalar> {
|
impl Vec2<Scalar> {
|
||||||
pub fn normal2(self) -> Scalar {
|
pub fn normal2(self) -> Scalar {
|
||||||
self.x * self.x + self.y * self.y
|
self.x * self.x + self.y * self.y
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normal(self) -> Scalar {
|
pub fn normal(self) -> Scalar {
|
||||||
self.normal2().sqrt()
|
self.normal2().sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn normalize(self) -> Vec2<Scalar> {
|
pub fn normalize(self) -> Vec2<Scalar> {
|
||||||
self.clone() / self.normal()
|
self.clone() / self.normal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vec2<Value> {
|
impl Vec2<Value> {
|
||||||
pub fn simplify(self) -> Self {
|
pub fn simplify(self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: self.x.simplify(),
|
x: self.x.simplify(),
|
||||||
y: self.y.simplify(),
|
y: self.y.simplify(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Add<U>, U> ops::Add<Vec2<U>> for Vec2<T> {
|
impl<T: ops::Add<U>, U> ops::Add<Vec2<U>> for Vec2<T> {
|
||||||
type Output = Vec2<T::Output>;
|
type Output = Vec2<T::Output>;
|
||||||
fn add(self, rhs: Vec2<U>) -> Self::Output {
|
fn add(self, rhs: Vec2<U>) -> Self::Output {
|
||||||
Self::Output {
|
Self::Output {
|
||||||
x: self.x + rhs.x,
|
x: self.x + rhs.x,
|
||||||
y: self.y + rhs.y,
|
y: self.y + rhs.y,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Sub<U>, U> ops::Sub<Vec2<U>> for Vec2<T> {
|
impl<T: ops::Sub<U>, U> ops::Sub<Vec2<U>> for Vec2<T> {
|
||||||
type Output = Vec2<T::Output>;
|
type Output = Vec2<T::Output>;
|
||||||
fn sub(self, rhs: Vec2<U>) -> Self::Output {
|
fn sub(self, rhs: Vec2<U>) -> Self::Output {
|
||||||
Self::Output {
|
Self::Output {
|
||||||
x: self.x - rhs.x,
|
x: self.x - rhs.x,
|
||||||
y: self.y - rhs.y,
|
y: self.y - rhs.y,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Mul<U>, U: Clone> ops::Mul<U> for Vec2<T> {
|
impl<T: ops::Mul<U>, U: Clone> ops::Mul<U> for Vec2<T> {
|
||||||
type Output = Vec2<T::Output>;
|
type Output = Vec2<T::Output>;
|
||||||
fn mul(self, rhs: U) -> Self::Output {
|
fn mul(self, rhs: U) -> Self::Output {
|
||||||
Self::Output {
|
Self::Output {
|
||||||
x: self.x * rhs.clone(),
|
x: self.x * rhs.clone(),
|
||||||
y: self.y * rhs,
|
y: self.y * rhs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Div<U>, U: Clone> ops::Div<U> for Vec2<T> {
|
impl<T: ops::Div<U>, U: Clone> ops::Div<U> for Vec2<T> {
|
||||||
type Output = Vec2<T::Output>;
|
type Output = Vec2<T::Output>;
|
||||||
fn div(self, rhs: U) -> Self::Output {
|
fn div(self, rhs: U) -> Self::Output {
|
||||||
Self::Output {
|
Self::Output {
|
||||||
x: self.x / rhs.clone(),
|
x: self.x / rhs.clone(),
|
||||||
y: self.y / rhs,
|
y: self.y / rhs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub struct Point2<T> {
|
pub struct Point2<T> {
|
||||||
pub x: T,
|
pub x: T,
|
||||||
pub y: T,
|
pub y: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Point2<T> {
|
impl<T> Point2<T> {
|
||||||
pub fn new(x: T, y: T) -> Point2<T> {
|
pub fn new(x: T, y: T) -> Point2<T> {
|
||||||
Point2 { x, y }
|
Point2 { x, y }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point2<Value> {
|
impl Point2<Value> {
|
||||||
pub fn simplify(self) -> Self {
|
pub fn simplify(self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: self.x.distribute().simplify(),
|
x: self.x.distribute().simplify(),
|
||||||
y: self.y.distribute().simplify(),
|
y: self.y.distribute().simplify(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn evaluate_with(self, eqns: &Eqns) -> Self {
|
pub fn evaluate_with(self, eqns: &Eqns) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: self.x.evaluate_with(eqns),
|
x: self.x.evaluate_with(eqns),
|
||||||
y: self.y.evaluate_with(eqns),
|
y: self.y.evaluate_with(eqns),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Add<U>, U> ops::Add<Vec2<U>> for Point2<T> {
|
impl<T: ops::Add<U>, U> ops::Add<Vec2<U>> for Point2<T> {
|
||||||
type Output = Point2<T::Output>;
|
type Output = Point2<T::Output>;
|
||||||
fn add(self, rhs: Vec2<U>) -> Self::Output {
|
fn add(self, rhs: Vec2<U>) -> Self::Output {
|
||||||
Point2 {
|
Point2 {
|
||||||
x: self.x + rhs.x,
|
x: self.x + rhs.x,
|
||||||
y: self.y + rhs.y,
|
y: self.y + rhs.y,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Sub<U>, U> ops::Sub<Vec2<U>> for Point2<T> {
|
impl<T: ops::Sub<U>, U> ops::Sub<Vec2<U>> for Point2<T> {
|
||||||
type Output = Point2<T::Output>;
|
type Output = Point2<T::Output>;
|
||||||
fn sub(self, rhs: Vec2<U>) -> Self::Output {
|
fn sub(self, rhs: Vec2<U>) -> Self::Output {
|
||||||
Point2 {
|
Point2 {
|
||||||
x: self.x - rhs.x,
|
x: self.x - rhs.x,
|
||||||
y: self.y - rhs.y,
|
y: self.y - rhs.y,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ops::Sub<U>, U> ops::Sub<Point2<U>> for Point2<T> {
|
impl<T: ops::Sub<U>, U> ops::Sub<Point2<U>> for Point2<T> {
|
||||||
type Output = Vec2<T::Output>;
|
type Output = Vec2<T::Output>;
|
||||||
fn sub(self, rhs: Point2<U>) -> Self::Output {
|
fn sub(self, rhs: Point2<U>) -> Self::Output {
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: self.x - rhs.x,
|
x: self.x - rhs.x,
|
||||||
y: self.y - rhs.y,
|
y: self.y - rhs.y,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
impl<T: fmt::Display> fmt::Display for Point2<T> {
|
impl<T: fmt::Display> fmt::Display for Point2<T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "<{}, {}>", self.x, self.y)
|
write!(f, "<{}, {}>", self.x, self.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||||
pub struct Rot2 {
|
pub struct Rot2 {
|
||||||
cos: Scalar,
|
cos: Scalar,
|
||||||
sin: Scalar,
|
sin: Scalar,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Rot2 {
|
impl fmt::Display for Rot2 {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "<{}, {}>", self.cos, self.sin)
|
write!(f, "<{}, {}>", self.cos, self.sin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rot2 {
|
impl Rot2 {
|
||||||
pub fn from_cos_sin_unchecked(cos: Scalar, sin: Scalar) -> Self {
|
pub fn from_cos_sin_unchecked(cos: Scalar, sin: Scalar) -> Self {
|
||||||
Self { cos, sin }
|
Self { cos, sin }
|
||||||
}
|
|
||||||
|
|
||||||
pub fn up() -> Self {
|
|
||||||
Self { cos: 0., sin: 1. }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn right() -> Self {
|
|
||||||
Self { cos: 1., sin: 0. }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_cos_sin(cos: Scalar, sin: Scalar) -> Self {
|
|
||||||
Vec2 { x: cos, y: sin }.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_angle(angle: Scalar) -> Self {
|
|
||||||
Self {
|
|
||||||
cos: angle.cos().into(),
|
|
||||||
sin: angle.sin().into(),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_angle_deg(angle_deg: Scalar) -> Self {
|
pub fn up() -> Self {
|
||||||
Self::from_angle(angle_deg * std::f64::consts::PI / 180.)
|
Self { cos: 0., sin: 1. }
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cardinal(index: i64) -> Self {
|
|
||||||
match index % 4 {
|
|
||||||
0 => Rot2 {
|
|
||||||
cos: (1.).into(),
|
|
||||||
sin: (0.).into(),
|
|
||||||
},
|
|
||||||
1 => Rot2 {
|
|
||||||
cos: (0.).into(),
|
|
||||||
sin: (1.).into(),
|
|
||||||
},
|
|
||||||
2 => Rot2 {
|
|
||||||
cos: (-1.).into(),
|
|
||||||
sin: (0.).into(),
|
|
||||||
},
|
|
||||||
3 => Rot2 {
|
|
||||||
cos: (0.).into(),
|
|
||||||
sin: (-1.).into(),
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cos(&self) -> Scalar {
|
pub fn right() -> Self {
|
||||||
self.cos
|
Self { cos: 1., sin: 0. }
|
||||||
}
|
|
||||||
|
|
||||||
pub fn sin(&self) -> Scalar {
|
|
||||||
self.sin
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn conj(self) -> Self {
|
|
||||||
Self {
|
|
||||||
cos: self.cos,
|
|
||||||
sin: -self.sin,
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dot(self, v: Vec2<Value>) -> Value {
|
pub fn from_cos_sin(cos: Scalar, sin: Scalar) -> Self {
|
||||||
v.x * self.cos + v.y * self.sin
|
Vec2 { x: cos, y: sin }.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_angle(angle: Scalar) -> Self {
|
||||||
|
Self {
|
||||||
|
cos: angle.cos().into(),
|
||||||
|
sin: angle.sin().into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_angle_deg(angle_deg: Scalar) -> Self {
|
||||||
|
Self::from_angle(angle_deg * std::f64::consts::PI / 180.)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cardinal(index: i64) -> Self {
|
||||||
|
match index % 4 {
|
||||||
|
0 => Rot2 {
|
||||||
|
cos: (1.).into(),
|
||||||
|
sin: (0.).into(),
|
||||||
|
},
|
||||||
|
1 => Rot2 {
|
||||||
|
cos: (0.).into(),
|
||||||
|
sin: (1.).into(),
|
||||||
|
},
|
||||||
|
2 => Rot2 {
|
||||||
|
cos: (-1.).into(),
|
||||||
|
sin: (0.).into(),
|
||||||
|
},
|
||||||
|
3 => Rot2 {
|
||||||
|
cos: (0.).into(),
|
||||||
|
sin: (-1.).into(),
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cos(&self) -> Scalar {
|
||||||
|
self.cos
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sin(&self) -> Scalar {
|
||||||
|
self.sin
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn conj(self) -> Self {
|
||||||
|
Self {
|
||||||
|
cos: self.cos,
|
||||||
|
sin: -self.sin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dot(self, v: Vec2<Value>) -> Value {
|
||||||
|
v.x * self.cos + v.y * self.sin
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec2<Scalar>> for Rot2 {
|
impl From<Vec2<Scalar>> for Rot2 {
|
||||||
fn from(v: Vec2<Scalar>) -> Rot2 {
|
fn from(v: Vec2<Scalar>) -> Rot2 {
|
||||||
let v = v.normalize();
|
let v = v.normalize();
|
||||||
Rot2 { cos: v.x, sin: v.y }
|
Rot2 { cos: v.x, sin: v.y }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Scalar> for Rot2 {
|
impl ops::Mul<Scalar> for Rot2 {
|
||||||
type Output = Vec2<Scalar>;
|
type Output = Vec2<Scalar>;
|
||||||
fn mul(self, rhs: Scalar) -> Vec2<Scalar> {
|
fn mul(self, rhs: Scalar) -> Vec2<Scalar> {
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: self.cos * rhs,
|
x: self.cos * rhs,
|
||||||
y: self.sin * rhs,
|
y: self.sin * rhs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Value> for Rot2 {
|
impl ops::Mul<Value> for Rot2 {
|
||||||
type Output = Vec2<Value>;
|
type Output = Vec2<Value>;
|
||||||
fn mul(self, rhs: Value) -> Vec2<Value> {
|
fn mul(self, rhs: Value) -> Vec2<Value> {
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: rhs.clone() * self.cos,
|
x: rhs.clone() * self.cos,
|
||||||
y: rhs * self.sin,
|
y: rhs * self.sin,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Add<Rot2> for Rot2 {
|
impl ops::Add<Rot2> for Rot2 {
|
||||||
type Output = Rot2;
|
type Output = Rot2;
|
||||||
fn add(self, rhs: Rot2) -> Rot2 {
|
fn add(self, rhs: Rot2) -> Rot2 {
|
||||||
Rot2 {
|
Rot2 {
|
||||||
cos: self.cos.clone() * rhs.cos.clone() - self.sin.clone() * rhs.sin.clone(),
|
cos: self.cos.clone() * rhs.cos.clone() - self.sin.clone() * rhs.sin.clone(),
|
||||||
sin: self.cos * rhs.sin + self.sin * rhs.cos,
|
sin: self.cos * rhs.sin + self.sin * rhs.cos,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Sub<Rot2> for Rot2 {
|
impl ops::Sub<Rot2> for Rot2 {
|
||||||
type Output = Rot2;
|
type Output = Rot2;
|
||||||
fn sub(self, rhs: Rot2) -> Rot2 {
|
fn sub(self, rhs: Rot2) -> Rot2 {
|
||||||
Rot2 {
|
Rot2 {
|
||||||
cos: self.cos.clone() * rhs.cos.clone() + self.sin.clone() * rhs.sin.clone(),
|
cos: self.cos.clone() * rhs.cos.clone() + self.sin.clone() * rhs.sin.clone(),
|
||||||
sin: self.sin * rhs.cos - self.cos * rhs.sin,
|
sin: self.sin * rhs.cos - self.cos * rhs.sin,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Vec2<Scalar>> for Rot2 {
|
impl ops::Mul<Vec2<Scalar>> for Rot2 {
|
||||||
type Output = Vec2<Scalar>;
|
type Output = Vec2<Scalar>;
|
||||||
fn mul(self, rhs: Vec2<Scalar>) -> Vec2<Scalar> {
|
fn mul(self, rhs: Vec2<Scalar>) -> Vec2<Scalar> {
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: self.cos * rhs.x - self.sin * rhs.y,
|
x: self.cos * rhs.x - self.sin * rhs.y,
|
||||||
y: self.cos * rhs.y + self.sin * rhs.x,
|
y: self.cos * rhs.y + self.sin * rhs.x,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ops::Mul<Vec2<Value>> for Rot2 {
|
impl ops::Mul<Vec2<Value>> for Rot2 {
|
||||||
type Output = Vec2<Value>;
|
type Output = Vec2<Value>;
|
||||||
fn mul(self, rhs: Vec2<Value>) -> Vec2<Value> {
|
fn mul(self, rhs: Vec2<Value>) -> Vec2<Value> {
|
||||||
Vec2 {
|
Vec2 {
|
||||||
x: rhs.x.clone() * self.cos - rhs.y.clone() * self.sin,
|
x: rhs.x.clone() * self.cos - rhs.y.clone() * self.sin,
|
||||||
y: rhs.y * self.cos + rhs.x * self.sin,
|
y: rhs.y * self.cos + rhs.x * self.sin,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
@ -78,9 +95,9 @@ impl Relation for PointAngle {
|
|||||||
let r = self.angle.clone().conj() * (p2.clone() - p1.clone());
|
let r = self.angle.clone().conj() * (p2.clone() - p1.clone());
|
||||||
trace!("angle.cos: {}", r.x);
|
trace!("angle.cos: {}", r.x);
|
||||||
// if relative_eq!(r.y, 0.) {
|
// if relative_eq!(r.y, 0.) {
|
||||||
ResolveResult::Constrained
|
ResolveResult::Constrained
|
||||||
// } else {
|
// } else {
|
||||||
// ResolveResult::Overconstrained
|
// ResolveResult::Overconstrained
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
(Singleton(p), _) => constrain_line(p, &mut *p2),
|
(Singleton(p), _) => constrain_line(p, &mut *p2),
|
||||||
@ -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);
|
||||||
@ -136,9 +157,9 @@ impl Relation for AlignedDistance {
|
|||||||
let r = p2.clone() - p1.clone();
|
let r = p2.clone() - p1.clone();
|
||||||
let d = self.angle.dot(r);
|
let d = self.angle.dot(r);
|
||||||
// if relative_eq!(d, self.distance) {
|
// if relative_eq!(d, self.distance) {
|
||||||
ResolveResult::Constrained
|
ResolveResult::Constrained
|
||||||
// } else {
|
// } else {
|
||||||
// ResolveResult::Overconstrained
|
// ResolveResult::Overconstrained
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
(Singleton(pos), _) => constrain_line(pos.clone() + offset, &mut *p2),
|
(Singleton(pos), _) => constrain_line(pos.clone() + offset, &mut *p2),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user