Pass around routing state with a new `Head` struct

This commit is contained in:
Mikolaj Wielgus 2023-07-13 18:18:46 +02:00
parent 0770917a41
commit dabe364420
4 changed files with 79 additions and 107 deletions

View File

@ -15,10 +15,9 @@ pub struct Layout {
rules: Rules, rules: Rules,
} }
impl Default for Layout { pub struct Head {
fn default() -> Self { pub dot: DotIndex,
return Layout::new(); pub bend: Option<BendIndex>,
}
} }
impl Layout { impl Layout {
@ -29,8 +28,12 @@ impl Layout {
} }
} }
pub fn route_around_dot(&mut self, from: DotIndex, around: DotIndex, cw: bool, width: f64) -> DotIndex { pub fn route_start(&mut self, from: DotIndex) -> Head {
let from_circle = self.head_guidecircle(from, width); Head {dot: from, bend: None}
}
pub fn route_around_dot(&mut self, head: Head, around: DotIndex, cw: bool, width: f64) -> Head {
let from_circle = self.head_guidecircle(&head, width);
let conditions = Conditions { let conditions = Conditions {
lower_net: None, lower_net: None,
@ -41,15 +44,15 @@ impl Layout {
let to_circle = self.dot_guidecircle(around, width + 5.0, conditions); let to_circle = self.dot_guidecircle(around, width + 5.0, conditions);
let from_cw = self.mesh.cw(Index::Dot(from)); let from_cw = self.head_cw(&head);
let tangent_points = math::tangent_point_pair(from_circle, from_cw, to_circle, Some(cw)); let tangent_points = math::tangent_point_pair(from_circle, from_cw, to_circle, Some(cw));
self.extend_head(from, tangent_points.0); let head = self.extend_head(head, tangent_points.0);
self.route_seg_bend(from, Index::Dot(around), tangent_points.1, cw, width) self.route_seg_bend(head, Index::Dot(around), tangent_points.1, cw, width)
} }
pub fn route_around_bend(&mut self, from: DotIndex, around: BendIndex, cw: bool, width: f64) -> DotIndex { pub fn route_around_bend(&mut self, head: Head, around: BendIndex, cw: bool, width: f64) -> Head {
let from_circle = self.head_guidecircle(from, width); let from_circle = self.head_guidecircle(&head, width);
let conditions = Conditions { let conditions = Conditions {
lower_net: None, lower_net: None,
@ -60,15 +63,15 @@ impl Layout {
let to_circle = self.bend_guidecircle(around, width, conditions); let to_circle = self.bend_guidecircle(around, width, conditions);
let from_cw = self.mesh.cw(Index::Dot(from)); let from_cw = self.head_cw(&head);
let tangent_points = math::tangent_point_pair(from_circle, from_cw, to_circle, Some(cw)); let tangent_points = math::tangent_point_pair(from_circle, from_cw, to_circle, Some(cw));
self.extend_head(from, tangent_points.0); let head = self.extend_head(head, tangent_points.0);
self.route_seg_bend(from, Index::Bend(around), tangent_points.1, cw, width) self.route_seg_bend(head, Index::Bend(around), tangent_points.1, cw, width)
} }
pub fn route_to(&mut self, from: DotIndex, to: DotIndex, width: f64) -> DotIndex { pub fn route_end(&mut self, head: Head, to: DotIndex, width: f64) {
let from_circle = self.head_guidecircle(from, width); let from_circle = self.head_guidecircle(&head, width);
let conditions = Conditions { let conditions = Conditions {
lower_net: None, lower_net: None,
@ -82,18 +85,17 @@ impl Layout {
r: 0.0, r: 0.0,
}; };
let from_cw = self.mesh.cw(Index::Dot(from)); let from_cw = self.head_cw(&head);
let tangent_points = math::tangent_point_pair(from_circle, from_cw, to_circle, None); let tangent_points = math::tangent_point_pair(from_circle, from_cw, to_circle, None);
self.extend_head(from, tangent_points.0); let head = self.extend_head(head, tangent_points.0);
self.add_seg(from, to, width); self.add_seg(head.dot, to, width);
to
} }
fn route_seg_bend(&mut self, from: DotIndex, around: Index, to: Point, cw: bool, width: f64) -> DotIndex { fn route_seg_bend(&mut self, head: Head, around: Index, to: Point, cw: bool, width: f64) -> Head {
let bend_from = self.route_seg(from, to, width); let head = self.route_seg(head, to, width);
let bend_to = self.add_dot(*self.mesh.primitive(Index::Dot(bend_from)).weight.as_dot().unwrap()); let bend_to = self.add_dot(*self.mesh.primitive(Index::Dot(head.dot)).weight.as_dot().unwrap());
let from_primitive = self.mesh.primitive(Index::Dot(from)); let from_primitive = self.mesh.primitive(Index::Dot(head.dot));
let net = from_primitive.weight.as_dot().unwrap().net; let net = from_primitive.weight.as_dot().unwrap().net;
let mut layer = around; let mut layer = around;
@ -102,12 +104,12 @@ impl Layout {
} }
let center = *layer.as_dot().unwrap(); let center = *layer.as_dot().unwrap();
let bend = self.mesh.add_bend(bend_from, bend_to, BendWeight {net, around, center, cw}); let bend = self.mesh.add_bend(head.dot, bend_to, BendWeight {net, around, center, cw});
bend_to Head {dot: bend_to, bend: Some(bend)}
} }
fn route_seg(&mut self, from: DotIndex, to: Point, width: f64) -> DotIndex { fn route_seg(&mut self, head: Head, to: Point, width: f64) -> Head {
let from_primitive = self.mesh.primitive(Index::Dot(from)); let from_primitive = self.mesh.primitive(Index::Dot(head.dot));
let net = from_primitive.weight.as_dot().unwrap().net; let net = from_primitive.weight.as_dot().unwrap().net;
assert!(width <= from_primitive.weight.as_dot().unwrap().circle.r * 2.0); assert!(width <= from_primitive.weight.as_dot().unwrap().circle.r * 2.0);
@ -116,12 +118,12 @@ impl Layout {
net, net,
circle: Circle {pos: to, r: width / 2.0}, circle: Circle {pos: to, r: width / 2.0},
}); });
self.mesh.add_seg(from, to_index, SegWeight {net, width}); self.mesh.add_seg(head.dot, to_index, SegWeight {net, width});
to_index Head {dot: to_index, bend: None}
} }
fn head_guidecircle(&self, head: DotIndex, width: f64) -> Circle { fn head_guidecircle(&self, head: &Head, width: f64) -> Circle {
let maybe_bend = self.mesh.bend(head); let maybe_bend = head.bend;
let conditions = Conditions { let conditions = Conditions {
lower_net: None, lower_net: None,
@ -141,12 +143,19 @@ impl Layout {
} }
}, },
None => Circle { None => Circle {
pos: self.mesh.weight(Index::Dot(head)).as_dot().unwrap().circle.pos, pos: self.mesh.weight(Index::Dot(head.dot)).as_dot().unwrap().circle.pos,
r: 0.0, r: 0.0,
}, },
} }
} }
fn head_cw(&self, head: &Head) -> Option<bool> {
match head.bend {
Some(bend) => Some(self.mesh.weight(Index::Bend(bend)).as_bend().unwrap().cw,),
None => None,
}
}
fn dot_guidecircle(&self, dot: DotIndex, width: f64, conditions: Conditions) -> Circle { fn dot_guidecircle(&self, dot: DotIndex, width: f64, conditions: Conditions) -> Circle {
let circle = self.mesh.weight(Index::Dot(dot)).as_dot().unwrap().circle; let circle = self.mesh.weight(Index::Dot(dot)).as_dot().unwrap().circle;
Circle { Circle {
@ -171,10 +180,11 @@ impl Layout {
} }
} }
fn extend_head(&mut self, from: DotIndex, to: Point) { fn extend_head(&mut self, head: Head, to: Point) -> Head {
if let Some(..) = self.mesh.bend(from) { if let Some(..) = head.bend {
self.extend_head_bend(from, to); self.extend_head_bend(head, to)
} else { } else {
head
// No assertion for now because we temporarily use floats. // No assertion for now because we temporarily use floats.
//println!("{:?} {:?}", self.mesh.weight(Index::Dot(from)).as_dot().unwrap().circle.pos, to); //println!("{:?} {:?}", self.mesh.weight(Index::Dot(from)).as_dot().unwrap().circle.pos, to);
@ -182,18 +192,18 @@ impl Layout {
} }
} }
fn extend_head_bend(&mut self, dot: DotIndex, to: Point) { fn extend_head_bend(&mut self, head: Head, to: Point) -> Head {
let bend = self.mesh.bend(dot).unwrap(); let bend = head.bend.unwrap();
let dot_weight = *self.mesh.weight(Index::Dot(dot)).as_dot().unwrap(); let dot_weight = *self.mesh.weight(Index::Dot(head.dot)).as_dot().unwrap();
let bend_weight = *self.mesh.weight(Index::Bend(bend)).as_bend().unwrap(); let bend_weight = *self.mesh.weight(Index::Bend(bend)).as_bend().unwrap();
let fixed_dot: Index = self.mesh.dot_neighbors(Index::Bend(bend)) let fixed_dot: Index = self.mesh.dot_neighbors(Index::Bend(bend))
.into_iter() .into_iter()
.filter(|neighbor| *neighbor != Index::Dot(dot)) .filter(|neighbor| *neighbor != Index::Dot(head.dot))
.collect::<Vec<Index>>()[0]; .collect::<Vec<Index>>()[0];
self.mesh.remove_bend(bend); self.mesh.remove_bend(bend);
self.mesh.remove_dot(dot); self.mesh.remove_dot(head.dot);
let new_dot = self.mesh.add_dot(DotWeight { let new_dot = self.mesh.add_dot(DotWeight {
net: dot_weight.net, net: dot_weight.net,
@ -203,6 +213,7 @@ impl Layout {
}, },
}); });
self.mesh.add_bend(*fixed_dot.as_dot().unwrap(), new_dot, bend_weight); self.mesh.add_bend(*fixed_dot.as_dot().unwrap(), new_dot, bend_weight);
head
} }
pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex { pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex {
@ -227,7 +238,7 @@ impl Layout {
return self.mesh.primitive(index); return self.mesh.primitive(index);
} }
pub fn bend(&self, index: DotIndex) -> Option<BendIndex> { /*pub fn bend(&self, index: DotIndex) -> Option<BendIndex> {
return self.mesh.bend(index); return self.mesh.bend(index);
} }*/
} }

View File

@ -62,26 +62,32 @@ fn main() {
let dot3 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (160.5, 150.5).into(), r: 8.0}}); let dot3 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (160.5, 150.5).into(), r: 8.0}});
let obstacle_dot1 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (220.5, 250.5).into(), r: 8.0}}); let obstacle_dot1 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (220.5, 250.5).into(), r: 8.0}});
let obstacle_dot2 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (100.5, 250.5).into(), r: 8.0}}); let obstacle_dot2 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (70.5, 250.5).into(), r: 8.0}});
layout.add_seg(obstacle_dot1, obstacle_dot2, 16.0); layout.add_seg(obstacle_dot1, obstacle_dot2, 16.0);
let dot4 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (200.5, 350.5).into(), r: 8.0}}); let dot4 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (180.5, 380.5).into(), r: 8.0}});
let dot5 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (220.5, 380.5).into(), r: 8.0}}); let dot5 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (220.5, 380.5).into(), r: 8.0}});
let dot6 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (290.5, 380.5).into(), r: 8.0}}); let dot6 = layout.add_dot(DotWeight {net: 0, circle: Circle {pos: (290.5, 380.5).into(), r: 8.0}});
let index3_1 = layout.route_around_dot(dot3, obstacle_dot1, true, 5.0); let head = layout.route_start(dot3);
let index3_2 = layout.route_to(index3_1, dot4, 5.0); let head = layout.route_around_dot(head, obstacle_dot1, true, 5.0);
let dot3_1 = head.dot;
let bend3_1 = head.bend.unwrap();
layout.route_end(head, dot4, 5.0);
let index2_1 = layout.route_around_dot(dot2, dot3, true, 5.0); let head = layout.route_start(dot2);
let index2_2 = layout.route_around_bend(index2_1, layout.bend(index3_1).unwrap(), true, 5.0); let head = layout.route_around_dot(head, dot3, true, 5.0);
let index2_3 = layout.route_to(index2_2, dot5, 5.0); let dot2_1 = head.dot;
let bend2_1 = head.bend.unwrap();
let head = layout.route_around_bend(head, bend3_1, true, 5.0);
let dot2_2 = head.dot;
let bend2_2 = head.bend.unwrap();
layout.route_end(head, dot5, 5.0);
let index1_1 = layout.route_around_bend(dot1, layout.bend(index2_1).unwrap(), true, 5.0); let head = layout.route_start(dot1);
let index1_2 = layout.route_around_bend(index1_1, layout.bend(index2_2).unwrap(), true, 5.0); let head = layout.route_around_bend(head, bend2_1, true, 5.0);
let index1_3 = layout.route_to(index1_2, dot6, 5.0); let head = layout.route_around_bend(head, bend2_2, true, 5.0);
layout.route_end(head, dot6, 5.0);
//
//layout.route_around_bend(dot1, layout.bend(index2).unwrap(), true, 5.0);
'running: loop { 'running: loop {
i = (i + 1) % 255; i = (i + 1) % 255;

View File

@ -25,12 +25,6 @@ pub struct Mesh {
pub graph: StableUnGraph<Weight, Weight, u32>, pub graph: StableUnGraph<Weight, Weight, u32>,
} }
impl Default for Mesh {
fn default() -> Self {
return Mesh::new();
}
}
impl Mesh { impl Mesh {
pub fn new() -> Self { pub fn new() -> Self {
return Mesh { return Mesh {
@ -93,7 +87,7 @@ impl Mesh {
}, },
_ => None, _ => None,
}, },
center: match index { focus: match index {
Index::Bend(bend_index) => { Index::Bend(bend_index) => {
let mut layer = index; let mut layer = index;
while let Index::Bend(..) = layer { while let Index::Bend(..) = layer {
@ -117,47 +111,8 @@ impl Mesh {
} }
} }
pub fn cw(&self, index: Index) -> Option<bool> {
match index {
Index::Dot(node_index) => {
let maybe_bend = self.bend(node_index);
match maybe_bend {
Some(bend) => Some(self.weight(Index::Bend(bend)).as_bend().unwrap().cw),
None => None,
}
}
Index::Seg(edge_index) => None,
Index::Bend(edge_index) => Some(self.weight(index).as_bend().unwrap().cw),
}
}
pub fn bend(&self, index: DotIndex) -> Option<BendIndex> {
//let edges: Vec<EdgeIndex<u32>> = self.graph.edges(index).map(|r| r.id()).collect();
let bends: Vec<EdgeIndex<u32>> = self.graph.edges(index)
.filter_map(|r| match self.weight(Index::Bend(r.id())) {
Weight::Bend(..) => Some(r.id()),
_ => None,
})
.collect();
if bends.len() != 1 {
return None;
}
Some(bends[0])
/*if edges.len() == 0 {
return None;
}*/
/*if edges[0]
Some(edges[0])*/
//None
}
pub fn weight(&self, index: Index) -> Weight { pub fn weight(&self, index: Index) -> Weight {
return match index { match index {
Index::Dot(node_index) => Index::Dot(node_index) =>
*self.graph.node_weight(node_index).unwrap(), *self.graph.node_weight(node_index).unwrap(),
Index::Seg(edge_index) | Index::Bend(edge_index) => Index::Seg(edge_index) | Index::Bend(edge_index) =>

View File

@ -8,7 +8,7 @@ pub struct Primitive {
pub weight: Weight, pub weight: Weight,
pub dot_neighbor_weights: Vec<DotWeight>, pub dot_neighbor_weights: Vec<DotWeight>,
pub around_weight: Option<Weight>, pub around_weight: Option<Weight>,
pub center: Option<Point>, pub focus: Option<Point>,
} }
impl Primitive { impl Primitive {
@ -36,9 +36,9 @@ impl Primitive {
Weight::Dot(dot) => Some(dot.circle), Weight::Dot(dot) => Some(dot.circle),
Weight::Seg(seg) => None, Weight::Seg(seg) => None,
Weight::Bend(bend) => { Weight::Bend(bend) => {
let r = self.dot_neighbor_weights[0].circle.pos.euclidean_distance(&self.center.unwrap()); let r = self.dot_neighbor_weights[0].circle.pos.euclidean_distance(&self.focus.unwrap());
Some(Circle { Some(Circle {
pos: self.center.unwrap(), pos: self.focus.unwrap(),
r, r,
}) })
} }