overlay: minimize ratsnest edge lengths

This commit is contained in:
Mikolaj Wielgus 2024-04-22 17:59:19 +02:00
parent 44bbb20e62
commit 68df579308
2 changed files with 34 additions and 16 deletions

View File

@ -15,22 +15,22 @@ use crate::{
}, },
geometry::primitive::PrimitiveShapeTrait, geometry::primitive::PrimitiveShapeTrait,
layout::Layout, layout::Layout,
triangulation::{GetVertexIndex, Triangulation}, triangulation::{GetVertexIndex, Triangulation, TriangulationEdgeWeight},
}; };
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct TriangulationWeight { pub struct VertexWeight {
vertex: FixedDotIndex, vertex: FixedDotIndex,
pub pos: Point, pub pos: Point,
} }
impl GetVertexIndex<FixedDotIndex> for TriangulationWeight { impl GetVertexIndex<FixedDotIndex> for VertexWeight {
fn vertex_index(&self) -> FixedDotIndex { fn vertex_index(&self) -> FixedDotIndex {
self.vertex self.vertex
} }
} }
impl HasPosition for TriangulationWeight { impl HasPosition for VertexWeight {
type Scalar = f64; type Scalar = f64;
fn position(&self) -> Point2<Self::Scalar> { fn position(&self) -> Point2<Self::Scalar> {
Point2::new(self.pos.x(), self.pos.y()) Point2::new(self.pos.x(), self.pos.y())
@ -38,7 +38,7 @@ impl HasPosition for TriangulationWeight {
} }
pub struct Ratsnest { pub struct Ratsnest {
graph: StableUnGraph<TriangulationWeight, (), usize>, graph: StableUnGraph<VertexWeight, TriangulationEdgeWeight, usize>,
} }
impl Ratsnest { impl Ratsnest {
@ -55,7 +55,7 @@ impl Ratsnest {
match node { match node {
PrimitiveIndex::FixedDot(dot) => { PrimitiveIndex::FixedDot(dot) => {
triangulation.add_vertex(TriangulationWeight { triangulation.add_vertex(VertexWeight {
vertex: dot, vertex: dot,
pos: center, pos: center,
})?; })?;
@ -70,7 +70,7 @@ impl Ratsnest {
Ok(this) Ok(this)
} }
pub fn graph(&self) -> &StableUnGraph<TriangulationWeight, (), usize> { pub fn graph(&self) -> &StableUnGraph<VertexWeight, TriangulationEdgeWeight, usize> {
&self.graph &self.graph
} }
} }

View File

@ -1,6 +1,6 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use geo::{point, Point}; use geo::{point, EuclideanDistance, Point};
use petgraph::visit; use petgraph::visit;
use spade::{handles::FixedVertexHandle, DelaunayTriangulation, HasPosition, InsertionError}; use spade::{handles::FixedVertexHandle, DelaunayTriangulation, HasPosition, InsertionError};
@ -75,23 +75,29 @@ impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scal
type EdgeId = (I, I); type EdgeId = (I, I);
} }
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub struct TriangulationEdgeWeight {
length: f64,
}
impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>> impl<I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<Scalar = f64>>
visit::Data for Triangulation<I, W> visit::Data for Triangulation<I, W>
{ {
type NodeWeight = W; type NodeWeight = W;
type EdgeWeight = (); type EdgeWeight = TriangulationEdgeWeight;
} }
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct TriangulationEdgeReference<I> { pub struct TriangulationEdgeReference<I> {
from: I, from: I,
to: I, to: I,
weight: TriangulationEdgeWeight,
} }
impl<I: Copy> visit::EdgeRef for TriangulationEdgeReference<I> { impl<I: Copy> visit::EdgeRef for TriangulationEdgeReference<I> {
type NodeId = I; type NodeId = I;
type EdgeId = (I, I); type EdgeId = (I, I);
type Weight = (); type Weight = TriangulationEdgeWeight;
fn source(&self) -> Self::NodeId { fn source(&self) -> Self::NodeId {
self.from self.from
@ -102,7 +108,7 @@ impl<I: Copy> visit::EdgeRef for TriangulationEdgeReference<I> {
} }
fn weight(&self) -> &Self::Weight { fn weight(&self) -> &Self::Weight {
&() &self.weight
} }
fn id(&self) -> Self::EdgeId { fn id(&self) -> Self::EdgeId {
@ -133,9 +139,14 @@ impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<
fn edge_references(self) -> Self::EdgeReferences { fn edge_references(self) -> Self::EdgeReferences {
Box::new( Box::new(
spade::Triangulation::directed_edges(&self.triangulation).map(|edge| { spade::Triangulation::directed_edges(&self.triangulation).map(|edge| {
let from = self.vertex(edge.from().fix());
let to = self.vertex(edge.to().fix());
TriangulationEdgeReference { TriangulationEdgeReference {
from: self.vertex(edge.from().fix()), from,
to: self.vertex(edge.to().fix()), to,
weight: TriangulationEdgeWeight {
length: self.position(from).euclidean_distance(&self.position(to)),
},
} }
}), }),
) )
@ -151,9 +162,16 @@ impl<'a, I: Copy + PartialEq + GetNodeIndex, W: GetVertexIndex<I> + HasPosition<
Box::new( Box::new(
spade::Triangulation::vertex(&self.triangulation, self.handle(node)) spade::Triangulation::vertex(&self.triangulation, self.handle(node))
.out_edges() .out_edges()
.map(|edge| TriangulationEdgeReference { .map(|edge| {
from: self.vertex(edge.from().fix()), let from = self.vertex(edge.from().fix());
to: self.vertex(edge.to().fix()), let to = self.vertex(edge.to().fix());
TriangulationEdgeReference {
from,
to,
weight: TriangulationEdgeWeight {
length: self.position(from).euclidean_distance(&self.position(to)),
},
}
}), }),
) )
} }