|
|
@ -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(); |
|
|
|