Some small improvements to iteration in graph and layout code

This commit is contained in:
Mikolaj Wielgus 2023-08-28 04:12:25 +02:00
parent 14f6b9f870
commit 47b3ffba08
5 changed files with 69 additions and 38 deletions

View File

@ -1,6 +1,6 @@
use petgraph::stable_graph::StableDiGraph;
use crate::graph::{BendIndex, DotIndex, Label, Path, SegIndex, TaggedIndex, TaggedWeight};
use crate::graph::{BendIndex, DotIndex, Label, SegIndex, TaggedIndex, TaggedWeight, Walk};
use crate::primitive::{Bend, Dot, Seg};
pub struct Bow<'a> {
@ -18,13 +18,21 @@ impl<'a> Bow<'a> {
pub fn new(index: BendIndex, graph: &'a StableDiGraph<TaggedWeight, Label, usize>) -> Self {
let bend = index;
let seg1_dot2 = *Bend::new(bend, graph).prev().unwrap().as_dot().unwrap();
let seg1 = *Dot::new(seg1_dot2, graph).prev().unwrap().as_seg().unwrap();
let seg1_dot1 = *Seg::new(seg1, graph).prev().unwrap().as_dot().unwrap();
let seg1_dot2 = Bend::new(bend, graph).prev().unwrap();
let seg1 = *Dot::new(seg1_dot2, graph)
.tagged_prev()
.unwrap()
.as_seg()
.unwrap();
let seg1_dot1 = Seg::new(seg1, graph).prev().unwrap();
let seg2_dot1 = *Bend::new(bend, graph).next().unwrap().as_dot().unwrap();
let seg2 = *Dot::new(seg2_dot1, graph).next().unwrap().as_seg().unwrap();
let seg2_dot2 = *Seg::new(seg2, graph).next().unwrap().as_dot().unwrap();
let seg2_dot1 = Bend::new(bend, graph).next().unwrap();
let seg2 = *Dot::new(seg2_dot1, graph)
.tagged_next()
.unwrap()
.as_seg()
.unwrap();
let seg2_dot2 = Seg::new(seg2, graph).next().unwrap();
Self {
seg1_dot1,
@ -39,7 +47,7 @@ impl<'a> Bow<'a> {
}
}
impl<'a> Path for Bow<'a> {
impl<'a> Walk for Bow<'a> {
fn interior(&self) -> Vec<TaggedIndex> {
vec![
TaggedIndex::Seg(self.seg1),

View File

@ -4,7 +4,7 @@ use std::marker::PhantomData;
use crate::math::Circle;
pub trait Path {
pub trait Walk {
fn interior(&self) -> Vec<TaggedIndex>;
fn closure(&self) -> Vec<TaggedIndex>;
fn ends(&self) -> [DotIndex; 2];

View File

@ -8,8 +8,8 @@ use spade::{DelaunayTriangulation, HasPosition, Point2, Triangulation};
use crate::bow::Bow;
use crate::graph::{
BendIndex, BendWeight, DotIndex, DotWeight, Index, Label, Path, SegIndex, SegWeight, Tag,
TaggedIndex, TaggedWeight,
BendIndex, BendWeight, DotIndex, DotWeight, Index, Label, SegIndex, SegWeight, Tag,
TaggedIndex, TaggedWeight, Walk,
};
use crate::primitive::Primitive;
use crate::shape::Shape;
@ -261,8 +261,7 @@ impl Layout {
}
pub fn dots(&self) -> impl Iterator<Item = DotIndex> + '_ {
self.nodes()
.filter_map(|ni| ni.as_dot().and_then(|di| Some(*di)))
self.nodes().filter_map(|ni| ni.as_dot().map(|di| *di))
}
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {

View File

@ -1,11 +1,11 @@
use std::mem::{self, swap};
use petgraph::stable_graph::StableDiGraph;
use petgraph::stable_graph::{NodeIndex, StableDiGraph};
use petgraph::Direction::{Incoming, Outgoing};
use crate::graph::{
BendIndex, BendWeight, DotIndex, DotWeight, Index, Label, Path, SegIndex, SegWeight, Tag,
TaggedIndex, TaggedWeight,
BendIndex, BendWeight, DotIndex, DotWeight, Index, Label, SegIndex, SegWeight, Tag,
TaggedIndex, TaggedWeight, Walk,
};
use crate::math::{self, Circle};
use crate::shape::{BendShape, DotShape, SegShape, Shape};
@ -80,20 +80,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
.map(|index| Index::<Label>::new(index).retag(self.graph.node_weight(index).unwrap()))
}
pub fn next(&self) -> Option<TaggedIndex> {
self.graph
.neighbors_directed(self.index.index, Outgoing)
.filter(|ni| {
self.graph
.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap())
.unwrap()
.is_end()
})
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
.next()
}
pub fn next_akin(&self) -> Option<Index<Weight>> {
pub fn find_next_akin(&self) -> Option<Index<Weight>> {
let mut prev_index = self.index.index;
while let Some(index) = self
@ -120,20 +107,24 @@ impl<'a, Weight> Primitive<'a, Weight> {
None
}
pub fn prev(&self) -> Option<TaggedIndex> {
pub fn tagged_next(&self) -> Option<TaggedIndex> {
self.next_node()
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
}
fn next_node(&self) -> Option<NodeIndex<usize>> {
self.graph
.neighbors_directed(self.index.index, Incoming)
.neighbors_directed(self.index.index, Outgoing)
.filter(|ni| {
self.graph
.edge_weight(self.graph.find_edge(*ni, self.index.index).unwrap())
.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap())
.unwrap()
.is_end()
})
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
.next()
}
pub fn prev_akin(&self) -> Option<Index<Weight>> {
pub fn find_prev_akin(&self) -> Option<Index<Weight>> {
let mut prev_index = self.index.index;
while let Some(index) = self
@ -160,6 +151,23 @@ impl<'a, Weight> Primitive<'a, Weight> {
None
}
pub fn tagged_prev(&self) -> Option<TaggedIndex> {
self.prev_node()
.map(|ni| Index::<Label>::new(ni).retag(self.graph.node_weight(ni).unwrap()))
}
fn prev_node(&self) -> Option<NodeIndex<usize>> {
self.graph
.neighbors_directed(self.index.index, Incoming)
.filter(|ni| {
self.graph
.edge_weight(self.graph.find_edge(*ni, self.index.index).unwrap())
.unwrap()
.is_end()
})
.next()
}
pub fn core(&self) -> Option<DotIndex> {
self.graph
.neighbors(self.index.index)
@ -208,7 +216,7 @@ impl<'a, Weight> Primitive<'a, Weight> {
}
}
impl<'a, Weight> Path for Primitive<'a, Weight> {
impl<'a, Weight> Walk for Primitive<'a, Weight> {
fn interior(&self) -> Vec<TaggedIndex> {
vec![self.tagged_index()]
}
@ -288,6 +296,14 @@ impl<'a> Dot<'a> {
}
impl<'a> Seg<'a> {
pub fn next(&self) -> Option<DotIndex> {
self.next_node().map(|ni| DotIndex::new(ni))
}
pub fn prev(&self) -> Option<DotIndex> {
self.prev_node().map(|ni| DotIndex::new(ni))
}
pub fn weight(&self) -> SegWeight {
*self.tagged_weight().as_seg().unwrap()
}
@ -328,6 +344,14 @@ impl<'a> Bend<'a> {
.next()
}
pub fn next(&self) -> Option<DotIndex> {
self.next_node().map(|ni| DotIndex::new(ni))
}
pub fn prev(&self) -> Option<DotIndex> {
self.prev_node().map(|ni| DotIndex::new(ni))
}
pub fn weight(&self) -> BendWeight {
*self.tagged_weight().as_bend().unwrap()
}

View File

@ -307,7 +307,7 @@ impl Router {
fn relax_band(&mut self, bend: BendIndex) {
let mut prev_bend = bend;
while let Some(cur_bend) = self.layout.primitive(prev_bend).prev_akin() {
while let Some(cur_bend) = self.layout.primitive(prev_bend).find_prev_akin() {
if self.layout.primitive(cur_bend).cross_product() >= 0. {
self.release_bow(cur_bend);
}
@ -316,7 +316,7 @@ impl Router {
}
let mut prev_bend = bend;
while let Some(cur_bend) = self.layout.primitive(prev_bend).next_akin() {
while let Some(cur_bend) = self.layout.primitive(prev_bend).find_next_akin() {
if self.layout.primitive(cur_bend).cross_product() >= 0. {
self.release_bow(cur_bend);
}