mesh: Make it possible for fixed and loose bends to be vertices

But not adding tem to the mesh yet, as it's going to take some effort.
This commit is contained in:
Mikolaj Wielgus 2023-10-30 18:22:14 +00:00
parent b84dab9d09
commit a3cedff577
6 changed files with 72 additions and 49 deletions

View File

@ -5,13 +5,12 @@ use geo::{EuclideanLength, Point};
use crate::{
graph::{
BendIndex, DotIndex, FixedDotIndex, FixedSegWeight, GetNet, Index, LooseBendIndex,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegIndex, LooseSegWeight,
MakePrimitive,
LooseBendWeight, LooseDotIndex, LooseDotWeight, LooseSegWeight, MakePrimitive,
},
guide::Guide,
layout::Layout,
math::Circle,
primitive::{GetOtherEnd, GetWeight},
primitive::GetOtherEnd,
rules::{Conditions, Rules},
segbend::Segbend,
};

View File

@ -357,7 +357,7 @@ impl Layout {
}
pub fn nodes(&self) -> impl Iterator<Item = Index> + '_ {
self.node_indexes().map(|ni| {
self.node_indices().map(|ni| {
self.graph
.node_weight(ni.node_index())
.unwrap()
@ -366,7 +366,7 @@ impl Layout {
}
pub fn shapes(&self) -> impl Iterator<Item = Shape> + '_ {
self.node_indexes()
self.node_indices()
.map(|ni| ni.primitive(&self.graph).shape())
}
@ -374,7 +374,7 @@ impl Layout {
self.graph.node_count()
}
fn node_indexes(&self) -> impl Iterator<Item = Index> + '_ {
fn node_indices(&self) -> impl Iterator<Item = Index> + '_ {
self.rtree.iter().map(|wrapper| wrapper.data)
}
}

View File

@ -454,27 +454,27 @@ fn render_times(
//let result = panic::catch_unwind(|| {
for shape in layout.shapes() {
match shape {
Shape::Dot(FixedDot) => {
Shape::Dot(dot) => {
let _ = canvas.filled_circle(
FixedDot.c.pos.x() as i16,
FixedDot.c.pos.y() as i16,
FixedDot.c.r as i16,
dot.c.pos.x() as i16,
dot.c.pos.y() as i16,
dot.c.r as i16,
Color::RGB(200, 52, 52),
);
}
Shape::Seg(FixedSeg) => {
Shape::Seg(seg) => {
let _ = canvas.thick_line(
FixedSeg.from.x() as i16,
FixedSeg.from.y() as i16,
FixedSeg.to.x() as i16,
FixedSeg.to.y() as i16,
FixedSeg.width as u8,
seg.from.x() as i16,
seg.from.y() as i16,
seg.to.x() as i16,
seg.to.y() as i16,
seg.width as u8,
Color::RGB(200, 52, 52),
);
}
Shape::Bend(FixedBend) => {
let delta1 = FixedBend.from - FixedBend.c.pos;
let delta2 = FixedBend.to - FixedBend.c.pos;
Shape::Bend(bend) => {
let delta1 = bend.from - bend.c.pos;
let delta2 = bend.to - bend.c.pos;
let angle1 = delta1.y().atan2(delta1.x());
let angle2 = delta2.y().atan2(delta2.x());
@ -483,10 +483,10 @@ fn render_times(
let _ = canvas.arc(
//around_circle.pos.x() as i16,
//around_circle.pos.y() as i16,
FixedBend.c.pos.x() as i16,
FixedBend.c.pos.y() as i16,
bend.c.pos.x() as i16,
bend.c.pos.y() as i16,
//(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16,
(FixedBend.circle().r + (d as f64)) as i16,
(bend.circle().r + (d as f64)) as i16,
angle1.to_degrees() as i16,
angle2.to_degrees() as i16,
Color::RGB(200, 52, 52),

View File

@ -1,5 +1,7 @@
use enum_dispatch::enum_dispatch;
use fixedbitset::FixedBitSet;
use geo::{point, Point};
use petgraph::stable_graph::NodeIndex;
use petgraph::visit::{self, NodeIndexable};
use spade::{
handles::{DirectedEdgeHandle, FixedDirectedEdgeHandle, FixedVertexHandle},
@ -8,18 +10,26 @@ use spade::{
};
use crate::{
graph::{DotIndex, FixedDotIndex, GetNodeIndex, Index},
graph::{FixedBendIndex, FixedDotIndex, GetNodeIndex, Index, LooseBendIndex},
layout::Layout,
};
use crate::{primitive::MakeShape, shape::ShapeTrait};
#[derive(Debug, Clone)]
struct Vertex {
dot: FixedDotIndex,
graph_index: VertexGraphIndex,
x: f64,
y: f64,
}
#[enum_dispatch(GetNodeIndex)]
#[derive(Debug, Clone, Copy)]
pub enum VertexGraphIndex {
FixedDot(FixedDotIndex),
FixedBend(FixedBendIndex),
LooseBend(LooseBendIndex),
}
#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)]
pub struct VertexIndex {
handle: FixedVertexHandle,
@ -35,29 +45,30 @@ impl HasPosition for Vertex {
#[derive(Debug, Clone)]
pub struct Mesh {
triangulation: DelaunayTriangulation<Vertex>,
dot_to_vertex: Vec<Option<VertexIndex>>,
graph_index_to_vertex: Vec<Option<VertexIndex>>,
}
impl Mesh {
pub fn new() -> Self {
Self {
triangulation: DelaunayTriangulation::new(),
dot_to_vertex: Vec::new(),
graph_index_to_vertex: Vec::new(),
}
}
pub fn triangulate(&mut self, layout: &Layout) -> Result<(), InsertionError> {
self.triangulation.clear();
self.dot_to_vertex = Vec::new();
self.dot_to_vertex.resize(layout.graph.node_bound(), None);
self.graph_index_to_vertex = Vec::new();
self.graph_index_to_vertex
.resize(layout.graph.node_bound(), None);
for node in layout.nodes() {
if let Index::FixedDot(dot) = node {
let center = layout.primitive(dot).shape().center();
self.dot_to_vertex[dot.node_index().index()] = Some(VertexIndex {
self.graph_index_to_vertex[dot.node_index().index()] = Some(VertexIndex {
handle: self.triangulation.insert(Vertex {
dot,
graph_index: dot.into(),
x: center.x(),
y: center.y(),
})?,
@ -68,12 +79,15 @@ impl Mesh {
Ok(())
}
pub fn dot(&self, vertex: VertexIndex) -> FixedDotIndex {
self.triangulation.vertex(vertex.handle).as_ref().dot
pub fn graph_index(&self, vertex: VertexIndex) -> VertexGraphIndex {
self.triangulation
.vertex(vertex.handle)
.as_ref()
.graph_index
}
pub fn vertex(&self, dot: FixedDotIndex) -> VertexIndex {
self.dot_to_vertex[dot.node_index().index()].unwrap()
pub fn vertex(&self, graph_index: VertexGraphIndex) -> VertexIndex {
self.graph_index_to_vertex[graph_index.node_index().index()].unwrap()
}
pub fn position(&self, vertex: VertexIndex) -> Point {

View File

@ -3,7 +3,7 @@ use petgraph::visit::EdgeRef;
use spade::InsertionError;
use crate::astar::{astar, AstarStrategy, PathTracker};
use crate::graph::{DotIndex, FixedDotIndex};
use crate::graph::FixedDotIndex;
use crate::layout::Layout;
use crate::mesh::{Mesh, MeshEdgeReference, VertexIndex};
@ -26,12 +26,12 @@ pub struct Router {
struct RouterAstarStrategy<'a, RO: RouterObserver> {
tracer: Tracer<'a>,
trace: Trace,
to: VertexIndex,
to: FixedDotIndex,
observer: &'a mut RO,
}
impl<'a, RO: RouterObserver> RouterAstarStrategy<'a, RO> {
pub fn new(tracer: Tracer<'a>, trace: Trace, to: VertexIndex, observer: &'a mut RO) -> Self {
pub fn new(tracer: Tracer<'a>, trace: Trace, to: FixedDotIndex, observer: &'a mut RO) -> Self {
Self {
tracer,
trace,
@ -48,14 +48,12 @@ impl<'a, RO: RouterObserver> AstarStrategy<&Mesh, u64> for RouterAstarStrategy<'
self.tracer.rework_path(&mut self.trace, &new_path, 5.0);
self.observer.on_rework(&self.tracer, &self.trace);
self.tracer
.finish(&mut self.trace, self.tracer.mesh.dot(self.to), 5.0)
.is_ok()
self.tracer.finish(&mut self.trace, self.to, 5.0).is_ok()
}
fn edge_cost(&mut self, edge: MeshEdgeReference) -> Option<u64> {
self.observer.before_probe(&self.tracer, &self.trace, edge);
if edge.target() != self.to
if edge.target() != self.tracer.mesh.vertex(self.to.into())
&& self
.tracer
.step(&mut self.trace, edge.target(), 5.0)
@ -100,8 +98,8 @@ impl Router {
let (_cost, _path) = astar(
&mesh,
mesh.vertex(from),
&mut RouterAstarStrategy::new(tracer, trace, mesh.vertex(to), observer),
mesh.vertex(from.into()),
&mut RouterAstarStrategy::new(tracer, trace, to.into(), observer),
)
.unwrap(); // TODO.

View File

@ -1,10 +1,10 @@
use contracts::debug_ensures;
use crate::{
draw::{BareHead, Draw, Head, HeadTrait, SegbendHead},
draw::{BareHead, Draw, Head, SegbendHead},
graph::FixedDotIndex,
layout::Layout,
mesh::{Mesh, VertexIndex},
mesh::{Mesh, VertexGraphIndex, VertexIndex},
rules::Rules,
};
@ -31,7 +31,7 @@ impl<'a> Tracer<'a> {
pub fn start(&mut self, from: FixedDotIndex) -> Trace {
Trace {
path: vec![self.mesh.vertex(from)],
path: vec![self.mesh.vertex(from.into())],
head: BareHead { dot: from }.into(),
}
}
@ -81,14 +81,13 @@ impl<'a> Tracer<'a> {
#[debug_ensures(ret.is_ok() -> trace.path.len() == old(trace.path.len() + 1))]
#[debug_ensures(ret.is_err() -> trace.path.len() == old(trace.path.len()))]
pub fn step(&mut self, trace: &mut Trace, to: VertexIndex, width: f64) -> Result<(), ()> {
let to_dot = self.mesh.dot(to);
trace.head = self.wrap(trace.head, to_dot, width)?.into();
trace.head = self.wrap(trace.head, to, width)?.into();
trace.path.push(to);
Ok(())
}
fn wrap(&mut self, head: Head, around: FixedDotIndex, width: f64) -> Result<SegbendHead, ()> {
fn wrap(&mut self, head: Head, around: VertexIndex, width: f64) -> Result<SegbendHead, ()> {
/*let _around_pos = self.layout.primitive(around).weight().circle.pos;
let _around_primitive = self.layout.primitive(around);
@ -114,6 +113,19 @@ impl<'a> Tracer<'a> {
}
}*/
match self.mesh.graph_index(around) {
VertexGraphIndex::FixedDot(dot) => self.wrap_around_fixed_dot(head, dot, width),
VertexGraphIndex::FixedBend(_fixed_bend) => todo!(),
VertexGraphIndex::LooseBend(_loose_bend) => todo!(),
}
}
fn wrap_around_fixed_dot(
&mut self,
head: Head,
around: FixedDotIndex,
width: f64,
) -> Result<SegbendHead, ()> {
self.draw().segbend_around_dot(head, around.into(), width)
}