From 5ce35a535743cc7c73a094e5e4d04106eea67f6d Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 23 Apr 2024 00:56:20 +0200 Subject: [PATCH] overlay: make ratlines between centers of pads instead of teir dots --- src/drawing/guide.rs | 5 ++++- src/geometry/poly.rs | 6 ++++- src/geometry/primitive.rs | 29 ++++++++++++------------ src/geometry/shape.rs | 1 + src/overlay/ratsnest.rs | 46 +++++++++++++++++++++++++++++---------- src/router/navmesh.rs | 2 +- src/router/router.rs | 15 ++++++++----- 7 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/drawing/guide.rs b/src/drawing/guide.rs index b15a68a..3baa43e 100644 --- a/src/drawing/guide.rs +++ b/src/drawing/guide.rs @@ -10,7 +10,10 @@ use crate::{ rules::GetConditions, Drawing, }, - geometry::primitive::{PrimitiveShape, PrimitiveShapeTrait}, + geometry::{ + primitive::{PrimitiveShape, PrimitiveShapeTrait}, + shape::ShapeTrait, + }, math::{self, Circle, NoTangents}, }; diff --git a/src/geometry/poly.rs b/src/geometry/poly.rs index c4e4b7f..85ebbe5 100644 --- a/src/geometry/poly.rs +++ b/src/geometry/poly.rs @@ -1,5 +1,5 @@ use enum_dispatch::enum_dispatch; -use geo::{Contains, Point, Polygon}; +use geo::{Centroid, Contains, Point, Polygon}; use crate::geometry::shape::ShapeTrait; @@ -9,6 +9,10 @@ pub struct PolyShape { } impl ShapeTrait for PolyShape { + fn center(&self) -> Point { + self.polygon.centroid().unwrap() + } + fn contains_point(&self, p: Point) -> bool { self.polygon.contains(&p) } diff --git a/src/geometry/primitive.rs b/src/geometry/primitive.rs index 7179f45..4f3a380 100644 --- a/src/geometry/primitive.rs +++ b/src/geometry/primitive.rs @@ -8,10 +8,9 @@ use crate::{ }; #[enum_dispatch] -pub trait PrimitiveShapeTrait { +pub trait PrimitiveShapeTrait: ShapeTrait { fn priority(&self) -> u64; fn inflate(&self, margin: f64) -> PrimitiveShape; - fn center(&self) -> Point; fn intersects(&self, other: &PrimitiveShape) -> bool; fn envelope(&self, margin: f64) -> AABB<[f64; 2]>; fn width(&self) -> f64; @@ -53,6 +52,10 @@ pub struct DotShape { } impl ShapeTrait for DotShape { + fn center(&self) -> Point { + self.c.pos + } + fn contains_point(&self, p: Point) -> bool { p.euclidean_distance(&self.c.pos) <= self.c.r } @@ -72,10 +75,6 @@ impl PrimitiveShapeTrait for DotShape { }) } - fn center(&self) -> Point { - self.c.pos - } - fn intersects(&self, other: &PrimitiveShape) -> bool { if self.priority() < other.priority() { return other.intersects(&PrimitiveShape::from(*self)); @@ -153,6 +152,10 @@ impl SegShape { } impl ShapeTrait for SegShape { + fn center(&self) -> Point { + (self.from + self.to) / 2.0 + } + fn contains_point(&self, p: Point) -> bool { self.polygon().contains(&p) } @@ -171,10 +174,6 @@ impl PrimitiveShapeTrait for SegShape { }) } - fn center(&self) -> Point { - (self.from + self.to) / 2.0 - } - fn intersects(&self, other: &PrimitiveShape) -> bool { if self.priority() < other.priority() { return other.intersects(&PrimitiveShape::from(*self)); @@ -268,6 +267,11 @@ impl BendShape { } impl ShapeTrait for BendShape { + fn center(&self) -> Point { + let sum = (self.from - self.c.pos) + (self.to - self.c.pos); + self.c.pos + (sum / sum.euclidean_distance(&point! {x: 0.0, y: 0.0})) * self.c.r + } + fn contains_point(&self, p: Point) -> bool { let d = p.euclidean_distance(&self.c.pos); self.between_ends(p) && d >= self.inner_circle().r && d <= self.outer_circle().r @@ -291,11 +295,6 @@ impl PrimitiveShapeTrait for BendShape { }) } - fn center(&self) -> Point { - let sum = (self.from - self.c.pos) + (self.to - self.c.pos); - self.c.pos + (sum / sum.euclidean_distance(&point! {x: 0.0, y: 0.0})) * self.c.r - } - fn intersects(&self, other: &PrimitiveShape) -> bool { if self.priority() < other.priority() { return other.intersects(&PrimitiveShape::from(*self)); diff --git a/src/geometry/shape.rs b/src/geometry/shape.rs index 9a9479c..b09311a 100644 --- a/src/geometry/shape.rs +++ b/src/geometry/shape.rs @@ -8,6 +8,7 @@ use crate::geometry::{ #[enum_dispatch] pub trait ShapeTrait { + fn center(&self) -> Point; fn contains_point(&self, p: Point) -> bool; } diff --git a/src/overlay/ratsnest.rs b/src/overlay/ratsnest.rs index 4150a13..a319d77 100644 --- a/src/overlay/ratsnest.rs +++ b/src/overlay/ratsnest.rs @@ -1,7 +1,8 @@ +use enum_dispatch::enum_dispatch; use geo::Point; use petgraph::{ data::FromElements, - stable_graph::StableUnGraph, + stable_graph::{NodeIndex, StableUnGraph}, visit::{self, EdgeRef, NodeIndexable}, }; use spade::{HasPosition, InsertionError, Point2}; @@ -13,19 +14,30 @@ use crate::{ primitive::MakePrimitiveShape, rules::RulesTrait, }, - geometry::primitive::PrimitiveShapeTrait, - layout::Layout, + geometry::{compound::CompoundManagerTrait, shape::ShapeTrait}, + graph::{GenericIndex, GetNodeIndex}, + layout::{ + zone::{MakePolyShape, ZoneWeight}, + Layout, + }, triangulation::{GetVertexIndex, Triangulation, TriangulationEdgeWeight}, }; +#[enum_dispatch(GetNodeIndex)] +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum RatsnestVertexIndex { + FixedDot(FixedDotIndex), + Zone(GenericIndex), +} + #[derive(Debug, Clone, Copy)] pub struct VertexWeight { - vertex: FixedDotIndex, + vertex: RatsnestVertexIndex, pub pos: Point, } -impl GetVertexIndex for VertexWeight { - fn vertex_index(&self) -> FixedDotIndex { +impl GetVertexIndex for VertexWeight { + fn vertex_index(&self) -> RatsnestVertexIndex { self.vertex } } @@ -51,19 +63,29 @@ impl Ratsnest { Triangulation::new(layout.drawing().geometry().graph().node_bound()); for node in layout.drawing().primitive_nodes() { - let center = node.primitive(layout.drawing()).shape().center(); - match node { PrimitiveIndex::FixedDot(dot) => { - triangulation.add_vertex(VertexWeight { - vertex: dot, - pos: center, - })?; + if layout.compounds(dot).next().is_none() { + triangulation.add_vertex(VertexWeight { + vertex: RatsnestVertexIndex::FixedDot(dot), + pos: node.primitive(layout.drawing()).shape().center(), + })?; + } } _ => (), } } + for zone in layout.zones() { + triangulation.add_vertex(VertexWeight { + vertex: RatsnestVertexIndex::Zone(zone), + pos: layout + .compound_weight(zone) + .shape(&layout.drawing(), zone) + .center(), + })? + } + this.graph = StableUnGraph::from_elements(petgraph::algo::min_spanning_tree(&triangulation)); diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index d118cf7..cf3c4de 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -7,6 +7,7 @@ use petgraph::visit::{self, NodeIndexable}; use petgraph::{stable_graph::NodeIndex, visit::EdgeRef}; use spade::{HasPosition, InsertionError, Point2}; +use crate::geometry::shape::ShapeTrait; use crate::{ drawing::{ bend::{FixedBendIndex, LooseBendIndex}, @@ -16,7 +17,6 @@ use crate::{ rules::RulesTrait, Drawing, }, - geometry::primitive::PrimitiveShapeTrait, graph::GetNodeIndex, layout::Layout, triangulation::{GetVertexIndex, Triangulation, TriangulationEdgeReference}, diff --git a/src/router/router.rs b/src/router/router.rs index e343b93..ffb86e6 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -4,15 +4,18 @@ use petgraph::visit::EdgeRef; use spade::InsertionError; use thiserror::Error; -use crate::drawing::{ - dot::FixedDotIndex, - graph::{MakePrimitive, PrimitiveIndex}, - primitive::MakePrimitiveShape, - rules::RulesTrait, -}; use crate::geometry::primitive::PrimitiveShapeTrait; use crate::layout::connectivity::BandIndex; use crate::layout::Layout; +use crate::{ + drawing::{ + dot::FixedDotIndex, + graph::{MakePrimitive, PrimitiveIndex}, + primitive::MakePrimitiveShape, + rules::RulesTrait, + }, + geometry::shape::ShapeTrait, +}; use crate::router::{ astar::{astar, AstarStrategy, PathTracker},