mirror of https://codeberg.org/topola/topola.git
Pass around routing state with a new `Head` struct
This commit is contained in:
parent
0770917a41
commit
dabe364420
|
|
@ -15,10 +15,9 @@ pub struct Layout {
|
|||
rules: Rules,
|
||||
}
|
||||
|
||||
impl Default for Layout {
|
||||
fn default() -> Self {
|
||||
return Layout::new();
|
||||
}
|
||||
pub struct Head {
|
||||
pub dot: DotIndex,
|
||||
pub bend: Option<BendIndex>,
|
||||
}
|
||||
|
||||
impl Layout {
|
||||
|
|
@ -29,8 +28,12 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn route_around_dot(&mut self, from: DotIndex, around: DotIndex, cw: bool, width: f64) -> DotIndex {
|
||||
let from_circle = self.head_guidecircle(from, width);
|
||||
pub fn route_start(&mut self, from: DotIndex) -> Head {
|
||||
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 {
|
||||
lower_net: None,
|
||||
|
|
@ -41,15 +44,15 @@ impl Layout {
|
|||
|
||||
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));
|
||||
|
||||
self.extend_head(from, tangent_points.0);
|
||||
self.route_seg_bend(from, Index::Dot(around), tangent_points.1, cw, width)
|
||||
let head = self.extend_head(head, tangent_points.0);
|
||||
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 {
|
||||
let from_circle = self.head_guidecircle(from, width);
|
||||
pub fn route_around_bend(&mut self, head: Head, around: BendIndex, cw: bool, width: f64) -> Head {
|
||||
let from_circle = self.head_guidecircle(&head, width);
|
||||
|
||||
let conditions = Conditions {
|
||||
lower_net: None,
|
||||
|
|
@ -60,15 +63,15 @@ impl Layout {
|
|||
|
||||
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));
|
||||
|
||||
self.extend_head(from, tangent_points.0);
|
||||
self.route_seg_bend(from, Index::Bend(around), tangent_points.1, cw, width)
|
||||
let head = self.extend_head(head, tangent_points.0);
|
||||
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 {
|
||||
let from_circle = self.head_guidecircle(from, width);
|
||||
pub fn route_end(&mut self, head: Head, to: DotIndex, width: f64) {
|
||||
let from_circle = self.head_guidecircle(&head, width);
|
||||
|
||||
let conditions = Conditions {
|
||||
lower_net: None,
|
||||
|
|
@ -82,18 +85,17 @@ impl Layout {
|
|||
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);
|
||||
|
||||
self.extend_head(from, tangent_points.0);
|
||||
self.add_seg(from, to, width);
|
||||
to
|
||||
let head = self.extend_head(head, tangent_points.0);
|
||||
self.add_seg(head.dot, to, width);
|
||||
}
|
||||
|
||||
fn route_seg_bend(&mut self, from: DotIndex, around: Index, to: Point, cw: bool, width: f64) -> DotIndex {
|
||||
let bend_from = self.route_seg(from, to, width);
|
||||
let bend_to = self.add_dot(*self.mesh.primitive(Index::Dot(bend_from)).weight.as_dot().unwrap());
|
||||
let from_primitive = self.mesh.primitive(Index::Dot(from));
|
||||
fn route_seg_bend(&mut self, head: Head, around: Index, to: Point, cw: bool, width: f64) -> Head {
|
||||
let head = self.route_seg(head, to, width);
|
||||
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(head.dot));
|
||||
let net = from_primitive.weight.as_dot().unwrap().net;
|
||||
|
||||
let mut layer = around;
|
||||
|
|
@ -102,12 +104,12 @@ impl Layout {
|
|||
}
|
||||
let center = *layer.as_dot().unwrap();
|
||||
|
||||
let bend = self.mesh.add_bend(bend_from, bend_to, BendWeight {net, around, center, cw});
|
||||
bend_to
|
||||
let bend = self.mesh.add_bend(head.dot, bend_to, BendWeight {net, around, center, cw});
|
||||
Head {dot: bend_to, bend: Some(bend)}
|
||||
}
|
||||
|
||||
fn route_seg(&mut self, from: DotIndex, to: Point, width: f64) -> DotIndex {
|
||||
let from_primitive = self.mesh.primitive(Index::Dot(from));
|
||||
fn route_seg(&mut self, head: Head, to: Point, width: f64) -> Head {
|
||||
let from_primitive = self.mesh.primitive(Index::Dot(head.dot));
|
||||
let net = from_primitive.weight.as_dot().unwrap().net;
|
||||
|
||||
assert!(width <= from_primitive.weight.as_dot().unwrap().circle.r * 2.0);
|
||||
|
|
@ -116,12 +118,12 @@ impl Layout {
|
|||
net,
|
||||
circle: Circle {pos: to, r: width / 2.0},
|
||||
});
|
||||
self.mesh.add_seg(from, to_index, SegWeight {net, width});
|
||||
to_index
|
||||
self.mesh.add_seg(head.dot, to_index, SegWeight {net, width});
|
||||
Head {dot: to_index, bend: None}
|
||||
}
|
||||
|
||||
fn head_guidecircle(&self, head: DotIndex, width: f64) -> Circle {
|
||||
let maybe_bend = self.mesh.bend(head);
|
||||
fn head_guidecircle(&self, head: &Head, width: f64) -> Circle {
|
||||
let maybe_bend = head.bend;
|
||||
|
||||
let conditions = Conditions {
|
||||
lower_net: None,
|
||||
|
|
@ -141,12 +143,19 @@ impl Layout {
|
|||
}
|
||||
},
|
||||
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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
let circle = self.mesh.weight(Index::Dot(dot)).as_dot().unwrap().circle;
|
||||
Circle {
|
||||
|
|
@ -171,10 +180,11 @@ impl Layout {
|
|||
}
|
||||
}
|
||||
|
||||
fn extend_head(&mut self, from: DotIndex, to: Point) {
|
||||
if let Some(..) = self.mesh.bend(from) {
|
||||
self.extend_head_bend(from, to);
|
||||
fn extend_head(&mut self, head: Head, to: Point) -> Head {
|
||||
if let Some(..) = head.bend {
|
||||
self.extend_head_bend(head, to)
|
||||
} else {
|
||||
head
|
||||
// No assertion for now because we temporarily use floats.
|
||||
|
||||
//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) {
|
||||
let bend = self.mesh.bend(dot).unwrap();
|
||||
let dot_weight = *self.mesh.weight(Index::Dot(dot)).as_dot().unwrap();
|
||||
fn extend_head_bend(&mut self, head: Head, to: Point) -> Head {
|
||||
let bend = head.bend.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 fixed_dot: Index = self.mesh.dot_neighbors(Index::Bend(bend))
|
||||
.into_iter()
|
||||
.filter(|neighbor| *neighbor != Index::Dot(dot))
|
||||
.filter(|neighbor| *neighbor != Index::Dot(head.dot))
|
||||
.collect::<Vec<Index>>()[0];
|
||||
|
||||
self.mesh.remove_bend(bend);
|
||||
self.mesh.remove_dot(dot);
|
||||
self.mesh.remove_dot(head.dot);
|
||||
|
||||
let new_dot = self.mesh.add_dot(DotWeight {
|
||||
net: dot_weight.net,
|
||||
|
|
@ -203,6 +213,7 @@ impl Layout {
|
|||
},
|
||||
});
|
||||
self.mesh.add_bend(*fixed_dot.as_dot().unwrap(), new_dot, bend_weight);
|
||||
head
|
||||
}
|
||||
|
||||
pub fn add_dot(&mut self, weight: DotWeight) -> DotIndex {
|
||||
|
|
@ -227,7 +238,7 @@ impl Layout {
|
|||
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);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
32
src/main.rs
32
src/main.rs
|
|
@ -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 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);
|
||||
|
||||
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 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 index3_2 = layout.route_to(index3_1, dot4, 5.0);
|
||||
let head = layout.route_start(dot3);
|
||||
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 index2_2 = layout.route_around_bend(index2_1, layout.bend(index3_1).unwrap(), true, 5.0);
|
||||
let index2_3 = layout.route_to(index2_2, dot5, 5.0);
|
||||
let head = layout.route_start(dot2);
|
||||
let head = layout.route_around_dot(head, dot3, true, 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 index1_2 = layout.route_around_bend(index1_1, layout.bend(index2_2).unwrap(), true, 5.0);
|
||||
let index1_3 = layout.route_to(index1_2, dot6, 5.0);
|
||||
|
||||
//
|
||||
//layout.route_around_bend(dot1, layout.bend(index2).unwrap(), true, 5.0);
|
||||
let head = layout.route_start(dot1);
|
||||
let head = layout.route_around_bend(head, bend2_1, true, 5.0);
|
||||
let head = layout.route_around_bend(head, bend2_2, true, 5.0);
|
||||
layout.route_end(head, dot6, 5.0);
|
||||
|
||||
'running: loop {
|
||||
i = (i + 1) % 255;
|
||||
|
|
|
|||
49
src/mesh.rs
49
src/mesh.rs
|
|
@ -25,12 +25,6 @@ pub struct Mesh {
|
|||
pub graph: StableUnGraph<Weight, Weight, u32>,
|
||||
}
|
||||
|
||||
impl Default for Mesh {
|
||||
fn default() -> Self {
|
||||
return Mesh::new();
|
||||
}
|
||||
}
|
||||
|
||||
impl Mesh {
|
||||
pub fn new() -> Self {
|
||||
return Mesh {
|
||||
|
|
@ -93,7 +87,7 @@ impl Mesh {
|
|||
},
|
||||
_ => None,
|
||||
},
|
||||
center: match index {
|
||||
focus: match index {
|
||||
Index::Bend(bend_index) => {
|
||||
let mut layer = index;
|
||||
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 {
|
||||
return match index {
|
||||
match index {
|
||||
Index::Dot(node_index) =>
|
||||
*self.graph.node_weight(node_index).unwrap(),
|
||||
Index::Seg(edge_index) | Index::Bend(edge_index) =>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ pub struct Primitive {
|
|||
pub weight: Weight,
|
||||
pub dot_neighbor_weights: Vec<DotWeight>,
|
||||
pub around_weight: Option<Weight>,
|
||||
pub center: Option<Point>,
|
||||
pub focus: Option<Point>,
|
||||
}
|
||||
|
||||
impl Primitive {
|
||||
|
|
@ -36,9 +36,9 @@ impl Primitive {
|
|||
Weight::Dot(dot) => Some(dot.circle),
|
||||
Weight::Seg(seg) => None,
|
||||
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 {
|
||||
pos: self.center.unwrap(),
|
||||
pos: self.focus.unwrap(),
|
||||
r,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue