Move routing methods to the `Route` struct

Commented out shove/squeeze features for now.
This commit is contained in:
Mikolaj Wielgus 2023-08-31 20:33:34 +02:00
parent 9f201d2c3d
commit e5ba7401c1
6 changed files with 131 additions and 99 deletions

View File

@ -5,11 +5,16 @@ use crate::{
guide::Guide, guide::Guide,
layout::Layout, layout::Layout,
math::Circle, math::Circle,
router::Head,
rules::{Conditions, Rules}, rules::{Conditions, Rules},
segbend::Segbend, segbend::Segbend,
}; };
#[derive(Debug, Clone, Copy)]
pub struct Head {
pub dot: DotIndex,
pub segbend: Option<Segbend>,
}
pub struct Draw<'a> { pub struct Draw<'a> {
layout: &'a mut Layout, layout: &'a mut Layout,
rules: &'a Rules, rules: &'a Rules,

View File

@ -1,10 +1,10 @@
use geo::Line; use geo::Line;
use crate::{ use crate::{
draw::Head,
graph::{BendIndex, DotIndex}, graph::{BendIndex, DotIndex},
layout::Layout, layout::Layout,
math::{self, Circle}, math::{self, Circle},
router::Head,
rules::{Conditions, Rules}, rules::{Conditions, Rules},
}; };

View File

@ -17,6 +17,7 @@ mod layout;
mod math; mod math;
mod mesh; mod mesh;
mod primitive; mod primitive;
mod route;
mod router; mod router;
mod rules; mod rules;
mod segbend; mod segbend;
@ -217,7 +218,7 @@ fn main() {
let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap(); let head = router.draw_around_dot(head, dot6, false, 5.0).unwrap();
let _ = router.draw_finish(head, dot7, 5.0);*/ let _ = router.draw_finish(head, dot7, 5.0);*/
router.route(dot1_1, dot1_2); router.enroute(dot1_1, dot1_2);
render_times(&mut event_pump, &mut canvas, &mut router, None, -1); render_times(&mut event_pump, &mut canvas, &mut router, None, -1);
render_times( render_times(
@ -257,10 +258,10 @@ fn render_times(
if let Some(follower) = follower { if let Some(follower) = follower {
let state = event_pump.mouse_state(); let state = event_pump.mouse_state();
let _ = router.move_dot( /*let _ = router.move_dot(
*follower.as_dot().unwrap(), *follower.as_dot().unwrap(),
(state.x() as f64, state.y() as f64).into(), (state.x() as f64, state.y() as f64).into(),
); );*/
} }
let result = panic::catch_unwind(|| { let result = panic::catch_unwind(|| {

View File

@ -1,8 +1,6 @@
use fixedbitset::FixedBitSet; use fixedbitset::FixedBitSet;
use geo::{point, Point}; use geo::{point, Point};
use petgraph::{ use petgraph::visit::{self, NodeIndexable};
visit::{self, NodeIndexable},
};
use spade::{ use spade::{
handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle}, handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle},
iterators::DirectedEdgeIterator, iterators::DirectedEdgeIterator,

92
src/route.rs Normal file
View File

@ -0,0 +1,92 @@
use crate::{
draw::{Draw, Head},
layout::Layout,
mesh::{Mesh, VertexIndex},
rules::Rules,
};
#[derive(Debug)]
pub struct Trace {
path: Vec<VertexIndex>,
head: Head,
}
pub struct Route<'a> {
layout: &'a mut Layout,
rules: &'a Rules,
mesh: &'a Mesh,
width: f64,
}
impl<'a> Route<'a> {
pub fn new(layout: &'a mut Layout, rules: &'a Rules, mesh: &'a Mesh, width: f64) -> Self {
Route {
layout,
rules,
mesh,
width,
}
}
pub fn start(&mut self, from: VertexIndex) -> Trace {
Trace {
path: vec![from],
head: Head {
dot: self.mesh.dot(from),
segbend: None,
},
}
}
pub fn finish(&mut self, trace: Trace, into: VertexIndex) {
let into_dot = self.mesh.dot(into);
let width = self.width;
self.draw().finish(trace.head, into_dot, width);
}
pub fn rework_path(&mut self, mut trace: Trace, path: &[VertexIndex]) -> Result<Trace, ()> {
let prefix_length = trace
.path
.iter()
.zip(path)
.take_while(|(v1, v2)| v1 == v2)
.count();
let length = trace.path.len();
trace = self.undo_path(trace, length - prefix_length)?;
self.path(trace, &path[prefix_length..])
}
pub fn path(&mut self, mut trace: Trace, path: &[VertexIndex]) -> Result<Trace, ()> {
for vertex in path {
trace = self.step(trace, *vertex)?;
}
Ok(trace)
}
pub fn undo_path(&mut self, mut trace: Trace, step_count: usize) -> Result<Trace, ()> {
for _ in 0..step_count {
trace = self.undo_step(trace)?;
}
Ok(trace)
}
pub fn step(&mut self, mut trace: Trace, to: VertexIndex) -> Result<Trace, ()> {
let to_dot = self.mesh.dot(to);
let width = self.width;
trace.head = self
.draw()
.segbend_around_dot(trace.head, to_dot, true, width)?;
Ok(trace)
}
pub fn undo_step(&mut self, mut trace: Trace) -> Result<Trace, ()> {
trace.head = self.draw().undo_segbend(trace.head).unwrap();
trace.path.pop();
Ok(trace)
}
fn draw(&mut self) -> Draw {
Draw::new(&mut self.layout, &self.rules)
}
}

View File

@ -4,7 +4,7 @@ use spade::InsertionError;
use crate::astar::astar; use crate::astar::astar;
use crate::bow::Bow; use crate::bow::Bow;
use crate::draw::Draw; use crate::draw::{Draw, Head};
use crate::graph::{BendIndex, DotIndex, Ends, SegIndex, TaggedIndex}; use crate::graph::{BendIndex, DotIndex, Ends, SegIndex, TaggedIndex};
use crate::graph::{BendWeight, DotWeight, SegWeight}; use crate::graph::{BendWeight, DotWeight, SegWeight};
use crate::guide::Guide; use crate::guide::Guide;
@ -12,123 +12,59 @@ use crate::layout::Layout;
use crate::math::Circle; use crate::math::Circle;
use crate::mesh::{Mesh, VertexIndex}; use crate::mesh::{Mesh, VertexIndex};
use crate::route::Route;
use crate::rules::{Conditions, Rules}; use crate::rules::{Conditions, Rules};
use crate::segbend::Segbend; use crate::segbend::Segbend;
pub struct Router { pub struct Router {
pub layout: Layout, pub layout: Layout,
mesh: Mesh,
rules: Rules, rules: Rules,
} }
struct Route {
path: Vec<VertexIndex>,
head: Head,
width: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct Head {
pub dot: DotIndex,
pub segbend: Option<Segbend>,
}
impl Router { impl Router {
pub fn new() -> Self { pub fn new() -> Self {
Router { Router {
layout: Layout::new(), layout: Layout::new(),
mesh: Mesh::new(),
rules: Rules::new(), rules: Rules::new(),
} }
} }
pub fn route(&mut self, from: DotIndex, to: DotIndex) -> Result<(), InsertionError> { pub fn enroute(&mut self, from: DotIndex, to: DotIndex) -> Result<(), InsertionError> {
// XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look // XXX: Should we actually store the mesh? May be useful for debugging, but doesn't look
// right. // right.
self.mesh.triangulate(&self.layout)?; //self.mesh.triangulate(&self.layout)?;
let mut mesh = Mesh::new();
mesh.triangulate(&self.layout)?;
let (_cost, mesh_path) = astar( let (_cost, path) = astar(
&self.mesh, &mesh,
self.mesh.vertex(from), mesh.vertex(from),
|node, tracker| { |node, tracker| {
let new_path = tracker.reconstruct_path_to(node); let new_path = tracker.reconstruct_path_to(node);
(node != self.mesh.vertex(to)).then_some(0) (node != mesh.vertex(to)).then_some(0)
}, },
|_edge| 1, |_edge| 1,
|_| 0, |_| 0,
) )
.unwrap(); // TODO. .unwrap(); // TODO.
let path: Vec<DotIndex> = mesh_path /*let path: Vec<DotIndex> = mesh_path
.iter() .iter()
.map(|vertex| self.mesh.dot(*vertex)) .map(|vertex| self.mesh.dot(*vertex))
.collect(); .collect();*/
let mut route = self.route_start(path[0], 5.0); let mut trace = self.route(&mesh, 5.0).start(path[0]);
route = self.route_path(route, &path[1..(path.len() - 1)]).unwrap(); // TODO. trace = self
let _ = self.route_finish(route, path[path.len() - 1]); .route(&mesh, 5.0)
.path(trace, &path[1..(path.len() - 1)])
.unwrap(); // TODO.
let _ = self.route(&mesh, 5.0).finish(trace, path[path.len() - 1]);
Ok(()) Ok(())
} }
fn route_start(&mut self, from: DotIndex, width: f64) -> Route { /*pub fn squeeze_around_dot(
Route {
path: vec![],
head: self.draw().start(from),
width,
}
}
fn route_finish(&mut self, route: Route, into: DotIndex) -> Result<(), ()> {
self.draw().finish(route.head, into, route.width)?;
Ok(())
}
fn route_path(&mut self, mut route: Route, path: &[DotIndex]) -> Result<Route, ()> {
for dot in path {
route = self.route_step(route, *dot)?;
}
Ok(route)
}
fn reroute_path(&mut self, mut route: Route, path: &[DotIndex]) -> Result<Route, ()> {
let prefix_length = route
.path
.iter()
.zip(path)
.take_while(|(vertex, dot)| **vertex == self.mesh.vertex(**dot))
.count();
let length = route.path.len();
route = self.unroute_steps(route, length - prefix_length)?;
route = self.route_path(route, &path[prefix_length..])?;
Ok(route)
}
fn unroute_step(&mut self, mut route: Route) -> Result<Route, ()> {
route.head = self.draw().undo_segbend(route.head).unwrap();
route.path.pop();
Ok(route)
}
fn unroute_steps(&mut self, mut route: Route, step_count: usize) -> Result<Route, ()> {
for _ in 0..step_count {
route = self.unroute_step(route)?;
}
Ok(route)
}
fn route_step(&mut self, mut route: Route, to: DotIndex) -> Result<Route, ()> {
route.head = self
.draw()
.segbend_around_dot(route.head, to, true, route.width)?;
route.path.push(self.mesh.vertex(to));
Ok(route)
}
pub fn squeeze_around_dot(
&mut self, &mut self,
head: Head, head: Head,
around: DotIndex, around: DotIndex,
@ -238,18 +174,18 @@ impl Router {
} }
Ok(()) Ok(())
}*/
pub fn route<'a>(&'a mut self, mesh: &'a Mesh, width: f64) -> Route {
Route::new(&mut self.layout, &self.rules, mesh, width)
} }
pub fn draw(&mut self) -> Draw { /*pub fn routeedges(&self) -> impl Iterator<Item = (Point, Point)> + '_ {
Draw::new(&mut self.layout, &self.rules)
}
pub fn routeedges(&self) -> impl Iterator<Item = (Point, Point)> + '_ {
self.mesh.edge_references().map(|edge| { self.mesh.edge_references().map(|edge| {
( (
self.mesh.position(edge.source()), self.mesh.position(edge.source()),
self.mesh.position(edge.target()), self.mesh.position(edge.target()),
) )
}) })
} }*/
} }