Create a new `Set` trait for collections of node indices

This commit is contained in:
Mikolaj Wielgus 2023-07-22 20:55:25 +02:00
parent f1772ca0be
commit 925448802a
7 changed files with 177 additions and 138 deletions

114
src/graph.rs Normal file
View File

@ -0,0 +1,114 @@
use std::marker::PhantomData;
use enum_as_inner::EnumAsInner;
use petgraph::stable_graph::NodeIndex;
use crate::math::Circle;
pub trait Set {
fn interior(&self) -> Vec<TaggedIndex>;
fn closure(&self) -> Vec<TaggedIndex>;
fn boundary(&self) -> Vec<DotIndex>;
}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum TaggedWeight {
Dot(DotWeight),
Seg(SegWeight),
Bend(BendWeight),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DotWeight {
pub net: i32,
pub circle: Circle,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BendWeight {
pub net: i32,
pub cw: bool,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SegWeight {
pub net: i32,
pub width: f64,
}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum Label {
End,
Outer,
Core,
}
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
pub enum TaggedIndex {
Dot(DotIndex),
Seg(SegIndex),
Bend(BendIndex),
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Index<T> {
pub index: NodeIndex<usize>,
marker: PhantomData<T>,
}
impl<T> Index<T> {
pub fn new(index: NodeIndex<usize>) -> Self {
Self {
index,
marker: PhantomData,
}
}
pub fn retag(&self, weight: TaggedWeight) -> TaggedIndex {
match weight {
TaggedWeight::Dot(..) =>
TaggedIndex::Dot(DotIndex {index: self.index, marker: PhantomData}),
TaggedWeight::Seg(..) =>
TaggedIndex::Seg(SegIndex {index: self.index, marker: PhantomData}),
TaggedWeight::Bend(..) =>
TaggedIndex::Bend(BendIndex {index: self.index, marker: PhantomData}),
}
}
}
pub trait Tag {
fn tag(&self) -> TaggedIndex;
}
macro_rules! untag {
($index:ident, $expr:expr) => {
match $index {
TaggedIndex::Dot($index) => $expr,
TaggedIndex::Seg($index) => $expr,
TaggedIndex::Bend($index) => $expr,
}
}
}
pub type DotIndex = Index<DotWeight>;
impl Tag for DotIndex {
fn tag(&self) -> TaggedIndex {
TaggedIndex::Dot(*self)
}
}
pub type SegIndex = Index<SegWeight>;
impl Tag for SegIndex {
fn tag(&self) -> TaggedIndex {
TaggedIndex::Seg(*self)
}
}
pub type BendIndex = Index<BendWeight>;
impl Tag for BendIndex {
fn tag(&self) -> TaggedIndex {
TaggedIndex::Bend(*self)
}
}

View File

@ -3,10 +3,11 @@ use std::rc::Rc;
use geo::geometry::Point;
use crate::math::Circle;
use crate::mesh::{Mesh, TaggedIndex, RTreeWrapper, DotIndex, SegIndex, BendIndex, Tag};
use crate::mesh::Mesh;
use crate::graph::{TaggedIndex, DotIndex, SegIndex, BendIndex};
use crate::rules::{Rules, Conditions};
use crate::shape::Shape;
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight};
use crate::graph::{TaggedWeight, DotWeight, SegWeight, BendWeight};
use crate::math;
pub struct Layout {
@ -182,28 +183,7 @@ impl Layout {
}
fn extend_head_bend(&mut self, head: Head, to: Point) -> Head {
let bend = head.bend.unwrap();
let dot_weight = self.mesh.primitive(head.dot).weight();
let bend_weight = self.mesh.primitive(bend).weight();
let around = self.mesh.primitive(bend).around();
let fixed_dot: DotIndex = self.mesh.primitive(bend).ends()
.into_iter()
.filter(|neighbor| {*neighbor != head.dot})
.collect::<Vec<DotIndex>>()[0];
self.mesh.remove_bend(bend);
self.mesh.remove_dot(head.dot);
let new_dot = self.mesh.add_dot(DotWeight {
net: dot_weight.net,
circle: Circle {
pos: to,
r: dot_weight.circle.r,
},
});
self.mesh.add_bend(fixed_dot, new_dot, around, bend_weight);
self.mesh.extend_bend(head.bend.unwrap(), head.dot, to);
head
}

View File

@ -1,25 +1,22 @@
extern crate sdl2;
#[macro_use] mod mesh;
#[macro_use] mod graph;
mod layout;
mod rules;
mod mesh;
mod primitive;
mod shape;
mod weight;
mod math;
use std::mem::swap;
use std::time::Duration;
use geo::geometry::Point;
use mesh::Index;
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::gfx::primitives::DrawRenderer;
use crate::layout::Layout;
use crate::shape::Shape;
use crate::weight::{TaggedWeight, DotWeight};
use crate::graph::DotWeight;
use crate::math::Circle;
fn main() {

View File

@ -1,76 +1,11 @@
use std::marker::PhantomData;
use enum_as_inner::EnumAsInner;
use geo::Point;
use petgraph::Direction::{Outgoing, Incoming};
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
use petgraph::visit::EdgeRef;
use rstar::{RTree, RTreeObject, AABB};
use petgraph::stable_graph::StableDiGraph;
use rstar::RTree;
use rstar::primitives::GeomWithData;
use crate::primitive::Primitive;
use crate::shape::Shape;
use crate::weight::{TaggedWeight, DotWeight, SegWeight, BendWeight, Label};
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Index<T> {
pub index: NodeIndex<usize>,
marker: PhantomData<T>,
}
impl<T> Index<T> {
pub fn new(index: NodeIndex<usize>) -> Self {
Self {
index,
marker: PhantomData,
}
}
}
pub trait Tag {
fn tag(&self) -> TaggedIndex;
}
macro_rules! untag {
($index:ident, $expr:expr) => {
match $index {
TaggedIndex::Dot($index) => $expr,
TaggedIndex::Seg($index) => $expr,
TaggedIndex::Bend($index) => $expr,
}
}
}
pub type DotIndex = Index<DotWeight>;
impl Tag for DotIndex {
fn tag(&self) -> TaggedIndex {
TaggedIndex::Dot(*self)
}
}
pub type SegIndex = Index<SegWeight>;
impl Tag for SegIndex {
fn tag(&self) -> TaggedIndex {
TaggedIndex::Seg(*self)
}
}
pub type BendIndex = Index<BendWeight>;
impl Tag for BendIndex {
fn tag(&self) -> TaggedIndex {
TaggedIndex::Bend(*self)
}
}
#[derive(Debug, EnumAsInner, Copy, Clone, PartialEq)]
pub enum TaggedIndex {
Dot(DotIndex),
Seg(SegIndex),
Bend(BendIndex),
}
use crate::graph::{Tag, TaggedIndex, DotIndex, SegIndex, BendIndex, Index, TaggedWeight, DotWeight, SegWeight, BendWeight, Label};
pub type RTreeWrapper = GeomWithData<Shape, TaggedIndex>;
@ -149,14 +84,30 @@ impl Mesh {
self.graph.remove_node(bend.index);
}
/*pub fn extend_bend(&mut self, bend: BendIndex, to: Point) -> DotIndex {
pub fn extend_bend(&mut self, bend: BendIndex, dot: DotIndex, to: Point) {
self.remove_from_rtree(bend.tag());
self.remove_from_rtree(dot.tag());
let mut dot_weight = self.primitive(dot).weight();
dot_weight.circle.pos = to;
*self.graph.node_weight_mut(dot.index).unwrap() = TaggedWeight::Dot(dot_weight);
self.insert_into_rtree(dot.tag());
self.insert_into_rtree(bend.tag());
}
pub fn shift_bend(&mut self, bend: BendIndex, offset: f64) {
/*pub fn shift_bend(&mut self, bend: BendIndex, offset: f64) {
}*/
/*pub fn position_bend(&mut self, bend: BendIndex, uI*/
//pub fn reposition_bend
pub fn reoffset_bend(&mut self, bend: BendIndex, offset: f64) {
}
pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
self.rtree.iter().map(|wrapper| wrapper.data)
}
@ -165,7 +116,13 @@ impl Mesh {
Primitive::new(index, &self.graph)
}
/*fn insert_into_rtree<Weight>(&mut self, index: Index<Weight>) {
self.rtree.insert(RTreeWrapper::new(self.primitive(index).shape(), index.tag()));
}*/
fn insert_into_rtree(&mut self, index: TaggedIndex) {
let shape = untag!(index, self.primitive(index).shape());
self.rtree.insert(RTreeWrapper::new(shape, index));
}
fn remove_from_rtree(&mut self, index: TaggedIndex) {
let shape = untag!(index, self.primitive(index).shape());
self.rtree.remove(&RTreeWrapper::new(shape, index));
}
}

View File

@ -3,7 +3,7 @@ use std::mem::swap;
use petgraph::Direction::{Outgoing, Incoming};
use petgraph::stable_graph::StableDiGraph;
use crate::{mesh::{DotIndex, SegIndex, BendIndex, TaggedIndex, Mesh, Tag, Index}, weight::{DotWeight, SegWeight, BendWeight, TaggedWeight, Label}};
use crate::graph::{Set, DotIndex, SegIndex, BendIndex, TaggedIndex, Tag, Index, DotWeight, SegWeight, BendWeight, TaggedWeight, Label};
use crate::shape::Shape;
pub struct Primitive<'a, Weight> {
@ -64,6 +64,10 @@ impl<'a, Weight> Primitive<'a, Weight> {
.next()
}
pub fn tagged_index(&self) -> TaggedIndex {
self.index.retag(*self.graph.node_weight(self.index.index).unwrap())
}
pub fn tagged_weight(&self) -> TaggedWeight {
*self.graph.node_weight(self.index.index).unwrap()
}
@ -73,6 +77,24 @@ impl<'a, Weight> Primitive<'a, Weight> {
}
}
impl<'a, Weight> Set for Primitive<'a, Weight> {
fn interior(&self) -> Vec<TaggedIndex> {
vec![self.tagged_index()]
}
fn closure(&self) -> Vec<TaggedIndex> {
let ends: Vec<TaggedIndex> = self.ends()
.into_iter()
.map(|end| TaggedIndex::Dot(end))
.collect();
[[self.tagged_index()].as_slice(), ends.as_slice()].concat()
}
fn boundary(&self) -> Vec<DotIndex> {
self.ends()
}
}
type Dot<'a> = Primitive<'a, DotWeight>;
type Seg<'a> = Primitive<'a, SegWeight>;
type Bend<'a> = Primitive<'a, BendWeight>;

View File

@ -1,7 +1,8 @@
use geo::{Point, EuclideanDistance};
use rstar::{RTreeObject, AABB};
use crate::{weight::{TaggedWeight, DotWeight}, math::Circle};
use crate::graph::{TaggedWeight, DotWeight};
use crate::math::Circle;
#[derive(PartialEq)]
pub struct Shape {

View File

@ -1,34 +1,2 @@
use enum_as_inner::EnumAsInner;
use crate::math::Circle;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DotWeight {
pub net: i32,
pub circle: Circle,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct BendWeight {
pub net: i32,
pub cw: bool,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SegWeight {
pub net: i32,
pub width: f64,
}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum TaggedWeight {
Dot(DotWeight),
Seg(SegWeight),
Bend(BendWeight),
}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum Label {
End,
Outer,
Core,
}