mirror of https://codeberg.org/topola/topola.git
Store width and points instead of weights in `Shape`
This commit is contained in:
parent
dea65a3b43
commit
f1772ca0be
|
|
@ -128,7 +128,7 @@ impl Layout {
|
||||||
if let Some(inner) = self.mesh.primitive(bend).inner() {
|
if let Some(inner) = self.mesh.primitive(bend).inner() {
|
||||||
self.bend_guidecircle(inner, width, conditions)
|
self.bend_guidecircle(inner, width, conditions)
|
||||||
} else {
|
} else {
|
||||||
self.dot_guidecircle(self.mesh.primitive(bend).core(), width + 5.0, conditions)
|
self.dot_guidecircle(self.mesh.primitive(bend).core().unwrap(), width + 5.0, conditions)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Circle {
|
None => Circle {
|
||||||
|
|
@ -158,11 +158,11 @@ impl Layout {
|
||||||
let mut layer = bend;
|
let mut layer = bend;
|
||||||
|
|
||||||
while let Some(inner) = self.mesh.primitive(layer).inner() {
|
while let Some(inner) = self.mesh.primitive(layer).inner() {
|
||||||
r += 5.0 + self.mesh.primitive(inner).shape().width();
|
r += 5.0 + self.mesh.primitive(inner).shape().width;
|
||||||
layer = inner;
|
layer = inner;
|
||||||
}
|
}
|
||||||
|
|
||||||
let core_circle = self.mesh.primitive(self.mesh.primitive(bend).core()).weight().circle;
|
let core_circle = self.mesh.primitive(self.mesh.primitive(bend).core().unwrap()).weight().circle;
|
||||||
Circle {
|
Circle {
|
||||||
pos: core_circle.pos,
|
pos: core_circle.pos,
|
||||||
r: core_circle.r + r + 15.0
|
r: core_circle.r + r + 15.0
|
||||||
|
|
|
||||||
43
src/main.rs
43
src/main.rs
|
|
@ -107,37 +107,14 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for shape in layout.shapes() {
|
for shape in layout.shapes() {
|
||||||
match shape.weight {
|
if let Some(center) = shape.center {
|
||||||
TaggedWeight::Dot(dot) => {
|
|
||||||
let _ = canvas.filled_circle(dot.circle.pos.x() as i16,
|
|
||||||
dot.circle.pos.y() as i16,
|
|
||||||
dot.circle.r as i16,
|
|
||||||
Color::RGB(200, 52, 52));
|
|
||||||
},
|
|
||||||
TaggedWeight::Seg(seg) => {
|
|
||||||
let dot_neighbor_weights = shape.dot_neighbor_weights;
|
|
||||||
let _ = canvas.thick_line(dot_neighbor_weights[0].circle.pos.x() as i16,
|
|
||||||
dot_neighbor_weights[0].circle.pos.y() as i16,
|
|
||||||
dot_neighbor_weights[1].circle.pos.x() as i16,
|
|
||||||
dot_neighbor_weights[1].circle.pos.y() as i16,
|
|
||||||
seg.width as u8,
|
|
||||||
Color::RGB(200, 52, 52));
|
|
||||||
},
|
|
||||||
TaggedWeight::Bend(bend) => {
|
|
||||||
let circle = shape.circle().unwrap();
|
let circle = shape.circle().unwrap();
|
||||||
let dot_neighbor_weights = shape.dot_neighbor_weights;
|
let delta1 = shape.from - circle.pos;
|
||||||
//let around_circle = shape.around_weight.unwrap().circle;
|
let delta2 = shape.to - circle.pos;
|
||||||
|
|
||||||
let delta1 = dot_neighbor_weights[0].circle.pos - circle.pos;
|
|
||||||
let delta2 = dot_neighbor_weights[1].circle.pos - circle.pos;
|
|
||||||
|
|
||||||
let mut angle1 = delta1.y().atan2(delta1.x());
|
let mut angle1 = delta1.y().atan2(delta1.x());
|
||||||
let mut angle2 = delta2.y().atan2(delta2.x());
|
let mut angle2 = delta2.y().atan2(delta2.x());
|
||||||
|
|
||||||
if shape.weight.as_bend().unwrap().cw {
|
|
||||||
swap(&mut angle1, &mut angle2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for d in -3..3 {
|
for d in -3..3 {
|
||||||
let _ = canvas.arc(
|
let _ = canvas.arc(
|
||||||
//around_circle.pos.x() as i16,
|
//around_circle.pos.x() as i16,
|
||||||
|
|
@ -150,8 +127,18 @@ fn main() {
|
||||||
angle2.to_degrees() as i16,
|
angle2.to_degrees() as i16,
|
||||||
Color::RGB(200, 52, 52));
|
Color::RGB(200, 52, 52));
|
||||||
}
|
}
|
||||||
|
} else if shape.from != shape.to {
|
||||||
},
|
let _ = canvas.thick_line(shape.from.x() as i16,
|
||||||
|
shape.from.y() as i16,
|
||||||
|
shape.to.x() as i16,
|
||||||
|
shape.to.y() as i16,
|
||||||
|
shape.width as u8,
|
||||||
|
Color::RGB(200, 52, 52));
|
||||||
|
} else {
|
||||||
|
let _ = canvas.filled_circle(shape.from.x() as i16,
|
||||||
|
shape.from.y() as i16,
|
||||||
|
(shape.width / 2.0) as i16,
|
||||||
|
Color::RGB(200, 52, 52));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
15
src/mesh.rs
15
src/mesh.rs
|
|
@ -1,5 +1,6 @@
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use enum_as_inner::EnumAsInner;
|
use enum_as_inner::EnumAsInner;
|
||||||
|
use geo::Point;
|
||||||
use petgraph::Direction::{Outgoing, Incoming};
|
use petgraph::Direction::{Outgoing, Incoming};
|
||||||
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
|
use petgraph::stable_graph::{StableDiGraph, NodeIndex, EdgeIndex};
|
||||||
use petgraph::visit::EdgeRef;
|
use petgraph::visit::EdgeRef;
|
||||||
|
|
@ -80,7 +81,7 @@ pub struct Mesh {
|
||||||
|
|
||||||
impl Mesh {
|
impl Mesh {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
return Mesh {
|
Mesh {
|
||||||
rtree: RTree::new(),
|
rtree: RTree::new(),
|
||||||
graph: StableDiGraph::default(),
|
graph: StableDiGraph::default(),
|
||||||
}
|
}
|
||||||
|
|
@ -148,6 +149,14 @@ impl Mesh {
|
||||||
self.graph.remove_node(bend.index);
|
self.graph.remove_node(bend.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*pub fn extend_bend(&mut self, bend: BendIndex, to: Point) -> DotIndex {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shift_bend(&mut self, bend: BendIndex, offset: f64) {
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
|
pub fn nodes(&self) -> impl Iterator<Item=TaggedIndex> + '_ {
|
||||||
self.rtree.iter().map(|wrapper| wrapper.data)
|
self.rtree.iter().map(|wrapper| wrapper.data)
|
||||||
}
|
}
|
||||||
|
|
@ -155,4 +164,8 @@ impl Mesh {
|
||||||
pub fn primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> {
|
pub fn primitive<Weight>(&self, index: Index<Weight>) -> Primitive<Weight> {
|
||||||
Primitive::new(index, &self.graph)
|
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()));
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
108
src/primitive.rs
108
src/primitive.rs
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::mem::swap;
|
||||||
|
|
||||||
use petgraph::Direction::{Outgoing, Incoming};
|
use petgraph::Direction::{Outgoing, Incoming};
|
||||||
use petgraph::stable_graph::StableDiGraph;
|
use petgraph::stable_graph::StableDiGraph;
|
||||||
|
|
||||||
|
|
@ -14,6 +16,54 @@ impl<'a, Weight> Primitive<'a, Weight> {
|
||||||
Primitive::<Weight> {index, graph}
|
Primitive::<Weight> {index, graph}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shape(&self) -> Shape {
|
||||||
|
let ends = self.ends();
|
||||||
|
match self.tagged_weight() {
|
||||||
|
TaggedWeight::Dot(dot) => Shape {
|
||||||
|
width: dot.circle.r * 2.0,
|
||||||
|
from: dot.circle.pos,
|
||||||
|
to: dot.circle.pos,
|
||||||
|
center: None,
|
||||||
|
},
|
||||||
|
TaggedWeight::Seg(seg) => {
|
||||||
|
Shape {
|
||||||
|
width: seg.width,
|
||||||
|
from: self.primitive(ends[0]).weight().circle.pos,
|
||||||
|
to: self.primitive(ends[1]).weight().circle.pos,
|
||||||
|
center: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TaggedWeight::Bend(bend) => {
|
||||||
|
let mut shape = Shape {
|
||||||
|
width: self.primitive(ends[0]).weight().circle.r * 2.0,
|
||||||
|
from: self.primitive(ends[0]).weight().circle.pos,
|
||||||
|
to: self.primitive(ends[1]).weight().circle.pos,
|
||||||
|
center: Some(self.primitive(self.core().unwrap()).weight().circle.pos),
|
||||||
|
};
|
||||||
|
|
||||||
|
if bend.cw {
|
||||||
|
swap(&mut shape.from, &mut shape.to);
|
||||||
|
}
|
||||||
|
shape
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ends(&self) -> Vec<DotIndex> {
|
||||||
|
self.graph.neighbors(self.index.index)
|
||||||
|
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end())
|
||||||
|
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
|
||||||
|
.map(|ni| DotIndex::new(ni))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn core(&self) -> Option<DotIndex> {
|
||||||
|
self.graph.neighbors(self.index.index)
|
||||||
|
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_core())
|
||||||
|
.map(|ni| DotIndex::new(ni))
|
||||||
|
.next()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn tagged_weight(&self) -> TaggedWeight {
|
pub fn tagged_weight(&self) -> TaggedWeight {
|
||||||
*self.graph.node_weight(self.index.index).unwrap()
|
*self.graph.node_weight(self.index.index).unwrap()
|
||||||
}
|
}
|
||||||
|
|
@ -28,82 +78,26 @@ type Seg<'a> = Primitive<'a, SegWeight>;
|
||||||
type Bend<'a> = Primitive<'a, BendWeight>;
|
type Bend<'a> = Primitive<'a, BendWeight>;
|
||||||
|
|
||||||
impl<'a> Dot<'a> {
|
impl<'a> Dot<'a> {
|
||||||
pub fn shape(&self) -> Shape {
|
|
||||||
Shape {
|
|
||||||
weight: self.tagged_weight(),
|
|
||||||
dot_neighbor_weights: vec![],
|
|
||||||
core_pos: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn weight(&self) -> DotWeight {
|
pub fn weight(&self) -> DotWeight {
|
||||||
*self.tagged_weight().as_dot().unwrap()
|
*self.tagged_weight().as_dot().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Seg<'a> {
|
impl<'a> Seg<'a> {
|
||||||
pub fn shape(&self) -> Shape {
|
|
||||||
Shape {
|
|
||||||
weight: self.tagged_weight(),
|
|
||||||
dot_neighbor_weights:
|
|
||||||
self.ends()
|
|
||||||
.into_iter()
|
|
||||||
.map(|index| self.primitive(index).weight())
|
|
||||||
.collect(),
|
|
||||||
core_pos: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ends(&self) -> Vec<DotIndex> {
|
|
||||||
self.graph.neighbors(self.index.index)
|
|
||||||
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end())
|
|
||||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
|
|
||||||
.map(|ni| DotIndex::new(ni))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn weight(&self) -> SegWeight {
|
pub fn weight(&self) -> SegWeight {
|
||||||
*self.tagged_weight().as_seg().unwrap()
|
*self.tagged_weight().as_seg().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Bend<'a> {
|
impl<'a> Bend<'a> {
|
||||||
pub fn shape(&self) -> Shape {
|
|
||||||
Shape {
|
|
||||||
weight: self.tagged_weight(),
|
|
||||||
dot_neighbor_weights:
|
|
||||||
self.ends()
|
|
||||||
.into_iter()
|
|
||||||
.map(|index| self.primitive(index).weight())
|
|
||||||
.collect(),
|
|
||||||
core_pos: Some(self.primitive(self.core()).weight().circle.pos),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ends(&self) -> Vec<DotIndex> {
|
|
||||||
self.graph.neighbors(self.index.index)
|
|
||||||
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_end())
|
|
||||||
.filter(|ni| self.graph.node_weight(*ni).unwrap().is_dot())
|
|
||||||
.map(|ni| DotIndex::new(ni))
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn around(&self) -> TaggedIndex {
|
pub fn around(&self) -> TaggedIndex {
|
||||||
if let Some(inner) = self.inner() {
|
if let Some(inner) = self.inner() {
|
||||||
TaggedIndex::Bend(inner)
|
TaggedIndex::Bend(inner)
|
||||||
} else {
|
} else {
|
||||||
TaggedIndex::Dot(self.core())
|
TaggedIndex::Dot(self.core().unwrap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn core(&self) -> DotIndex {
|
|
||||||
self.graph.neighbors(self.index.index)
|
|
||||||
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(self.index.index, *ni).unwrap()).unwrap().is_core())
|
|
||||||
.map(|ni| DotIndex::new(ni))
|
|
||||||
.next()
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn inner(&self) -> Option<BendIndex> {
|
pub fn inner(&self) -> Option<BendIndex> {
|
||||||
self.graph.neighbors_directed(self.index.index, Incoming)
|
self.graph.neighbors_directed(self.index.index, Incoming)
|
||||||
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(*ni, self.index.index).unwrap()).unwrap().is_outer())
|
.filter(|ni| self.graph.edge_weight(self.graph.find_edge(*ni, self.index.index).unwrap()).unwrap().is_outer())
|
||||||
|
|
|
||||||
59
src/shape.rs
59
src/shape.rs
|
|
@ -5,58 +5,43 @@ use crate::{weight::{TaggedWeight, DotWeight}, math::Circle};
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Shape {
|
pub struct Shape {
|
||||||
pub weight: TaggedWeight,
|
pub width: f64,
|
||||||
pub dot_neighbor_weights: Vec<DotWeight>,
|
pub from: Point,
|
||||||
pub core_pos: Option<Point>,
|
pub to: Point,
|
||||||
|
pub center: Option<Point>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Shape {
|
impl Shape {
|
||||||
pub fn envelope(&self) -> AABB<[f64; 2]> {
|
pub fn new(width: f64, from: Point, to: Point, center: Option<Point>) -> Self {
|
||||||
match self.weight {
|
Shape {width, from, to, center}
|
||||||
TaggedWeight::Dot(dot) => {
|
}
|
||||||
return AABB::from_corners(
|
|
||||||
[dot.circle.pos.x() - dot.circle.r, dot.circle.pos.y() - dot.circle.r],
|
|
||||||
[dot.circle.pos.x() + dot.circle.r, dot.circle.pos.y() + dot.circle.r]
|
|
||||||
);
|
|
||||||
},
|
|
||||||
TaggedWeight::Seg(..) | TaggedWeight::Bend(..) => {
|
|
||||||
// TODO: Take widths into account.
|
|
||||||
|
|
||||||
let points: Vec<[f64; 2]> = self.dot_neighbor_weights.iter()
|
pub fn envelope(&self) -> AABB<[f64; 2]> {
|
||||||
.map(|neighbor| [neighbor.circle.pos.x(), neighbor.circle.pos.y()])
|
if self.from == self.to {
|
||||||
.collect();
|
AABB::from_corners(
|
||||||
return AABB::<[f64; 2]>::from_points(&points);
|
[self.from.x() - self.width, self.from.y() - self.width],
|
||||||
},
|
[self.from.x() + self.width, self.from.y() + self.width]
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// TODO: Take widths into account.
|
||||||
|
AABB::<[f64; 2]>::from_points(&[[self.from.x(), self.from.y()],
|
||||||
|
[self.to.x(), self.to.y()]])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn circle(&self) -> Option<Circle> {
|
pub fn circle(&self) -> Option<Circle> {
|
||||||
match self.weight {
|
if let Some(center) = self.center {
|
||||||
TaggedWeight::Dot(dot) => Some(dot.circle),
|
let r = self.from.euclidean_distance(¢er);
|
||||||
TaggedWeight::Seg(seg) => None,
|
|
||||||
TaggedWeight::Bend(bend) => {
|
|
||||||
let r = self.dot_neighbor_weights[0].circle.pos.euclidean_distance(&self.core_pos.unwrap());
|
|
||||||
Some(Circle {
|
Some(Circle {
|
||||||
pos: self.core_pos.unwrap(),
|
pos: center,
|
||||||
r,
|
r,
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn width(&self) -> f64 {
|
|
||||||
match self.weight {
|
|
||||||
TaggedWeight::Dot(dot) => dot.circle.r * 2.0,
|
|
||||||
TaggedWeight::Seg(seg) => seg.width,
|
|
||||||
TaggedWeight::Bend(bend) => self.dot_neighbor_weights[0].circle.r * 2.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn weight(&self) -> TaggedWeight {
|
|
||||||
return self.weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RTreeObject for Shape {
|
impl RTreeObject for Shape {
|
||||||
type Envelope = AABB<[f64; 2]>;
|
type Envelope = AABB<[f64; 2]>;
|
||||||
fn envelope(&self) -> Self::Envelope {
|
fn envelope(&self) -> Self::Envelope {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue