From 14c3acb633d79e1ebda125e0198b0c40af64608a Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Tue, 8 Aug 2023 02:28:41 +0200 Subject: [PATCH] Change `Shape` from struct to enum It's more readable to use a match rather than an odd if condition. --- src/layout.rs | 2 +- src/main.rs | 67 ++++++++++++++++++++++++++---------------------- src/primitive.rs | 32 ++++++++++------------- src/shape.rs | 66 +++++++++++++++++++++++++++++------------------ 4 files changed, 93 insertions(+), 74 deletions(-) diff --git a/src/layout.rs b/src/layout.rs index 8e52d20..b60a117 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -286,7 +286,7 @@ impl Layout { let mut layer = bend; 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; } diff --git a/src/main.rs b/src/main.rs index 6a12ac2..2632303 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ mod math; use std::panic; use std::time::Duration; +use geo::EuclideanDistance; use graph::{TaggedIndex, Tag}; use sdl2::EventPump; use sdl2::pixels::Color; @@ -26,6 +27,7 @@ use sdl2::keyboard::Keycode; use sdl2::gfx::primitives::DrawRenderer; use sdl2::render::Canvas; use sdl2::video::Window; +use shape::Shape; use crate::layout::Layout; use crate::graph::DotWeight; @@ -205,44 +207,49 @@ fn render_times(event_pump: &mut EventPump, canvas: &mut Canvas, layout: let result = panic::catch_unwind(|| { for shape in layout.shapes() { - if let Some(center) = shape.center { - let circle = shape.circle().unwrap(); - let delta1 = shape.from - circle.pos; - let delta2 = shape.to - circle.pos; + match shape { + Shape::Dot(dot) => { + let _ = canvas.filled_circle(dot.c.pos.x() as i16, + dot.c.pos.y() as i16, + dot.c.r as i16, + Color::RGB(200, 52, 52)); + }, + Shape::Seg(seg) => { + let _ = canvas.thick_line(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(bend) => { + let delta1 = bend.from - bend.center; + let delta2 = bend.to - bend.center; + let r = bend.from.euclidean_distance(&bend.center); - let mut angle1 = delta1.y().atan2(delta1.x()); - let mut angle2 = delta2.y().atan2(delta2.x()); + let mut angle1 = delta1.y().atan2(delta1.x()); + let mut angle2 = delta2.y().atan2(delta2.x()); - for d in -2..3 { - let _ = canvas.arc( - //around_circle.pos.x() as i16, - //around_circle.pos.y() as i16, - circle.pos.x() as i16, - circle.pos.y() as i16, - //(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16, - (circle.r + (d as f64)) as i16, - angle1.to_degrees() as i16, - angle2.to_degrees() as i16, - 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)); + for d in -2..3 { + let _ = canvas.arc( + //around_circle.pos.x() as i16, + //around_circle.pos.y() as i16, + bend.center.x() as i16, + bend.center.y() as i16, + //(shape.around_weight.unwrap().circle.r + 10.0 + (d as f64)) as i16, + (r + (d as f64)) as i16, + angle1.to_degrees() as i16, + angle2.to_degrees() as i16, + Color::RGB(200, 52, 52)); + } + }, } /*let envelope = shape.envelope(); let _ = canvas.rectangle(envelope.lower()[0] as i16, envelope.lower()[1] as i16, envelope.upper()[0] as i16, envelope.upper()[1] as i16, + Color::RGB(100, 100, 100));*/ } }); diff --git a/src/primitive.rs b/src/primitive.rs index 7b9380f..bef6efa 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -5,7 +5,7 @@ use petgraph::stable_graph::StableDiGraph; use crate::graph::{Path, DotIndex, SegIndex, BendIndex, TaggedIndex, Tag, Index, DotWeight, SegWeight, BendWeight, TaggedWeight, Label}; use crate::math; -use crate::shape::Shape; +use crate::shape::{Shape, DotShape, SegShape, BendShape}; #[derive(Debug)] pub struct Primitive<'a, Weight> { @@ -20,35 +20,31 @@ impl<'a, Weight> Primitive<'a, Weight> { pub fn shape(&self) -> Shape { 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::Dot(dot) => Shape::Dot(DotShape { + c: dot.circle, + }), TaggedWeight::Seg(seg) => { let ends = self.ends(); - Shape { - width: seg.width, + Shape::Seg(SegShape { from: self.primitive(ends[0]).weight().circle.pos, to: self.primitive(ends[1]).weight().circle.pos, - center: None, - } - } + width: seg.width, + }) + }, TaggedWeight::Bend(bend) => { let ends = self.ends(); - let mut shape = Shape { - width: self.primitive(ends[0]).weight().circle.r * 2.0, + let mut bend_shape = BendShape { 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), + center: self.primitive(self.core().unwrap()).weight().circle.pos, + width: self.primitive(ends[0]).weight().circle.r * 2.0, }; if bend.cw { - swap(&mut shape.from, &mut shape.to); + swap(&mut bend_shape.from, &mut bend_shape.to); } - shape - } + Shape::Bend(bend_shape) + }, } } diff --git a/src/shape.rs b/src/shape.rs index 0363ae5..d00b7f0 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -5,40 +5,56 @@ use crate::graph::{TaggedWeight, DotWeight}; use crate::math::Circle; #[derive(Debug, PartialEq)] -pub struct Shape { - pub width: f64, +pub struct DotShape { + pub c: Circle, +} + +#[derive(Debug, PartialEq)] +pub struct SegShape { pub from: Point, pub to: Point, - pub center: Option, + pub width: f64, +} + +#[derive(Debug, PartialEq)] +pub struct BendShape { + pub from: Point, + pub to: Point, + pub center: Point, + pub width: f64, +} + +#[derive(Debug, PartialEq)] +pub enum Shape { + Dot(DotShape), + Seg(SegShape), + Bend(BendShape), } impl Shape { - pub fn new(width: f64, from: Point, to: Point, center: Option) -> Self { - Shape {width, from, to, center} - } - pub fn envelope(&self) -> AABB<[f64; 2]> { - if self.from == self.to { - AABB::from_corners( - [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()]]) + match self { + Shape::Dot(dot) => + AABB::from_corners( + [dot.c.pos.x() - dot.c.r, dot.c.pos.y() - dot.c.r], + [dot.c.pos.x() + dot.c.r, dot.c.pos.y() + dot.c.r], + ), + Shape::Seg(seg) => + AABB::<[f64; 2]>::from_points(&[[seg.from.x(), seg.from.y()], + [seg.to.x(), seg.to.y()]]), + Shape::Bend(bend) => + AABB::<[f64; 2]>::from_points(&[[bend.from.x() - bend.width, + bend.from.y() - bend.width], + [bend.to.x() + bend.width, + bend.to.y() + bend.width]]), } } - pub fn circle(&self) -> Option { - if let Some(center) = self.center { - let r = self.from.euclidean_distance(¢er); - Some(Circle { - pos: center, - r, - }) - } else { - None + pub fn width(&self) -> f64 { + match self { + Shape::Dot(dot) => dot.c.r * 2.0, + Shape::Seg(seg) => seg.width, + Shape::Bend(bend) => bend.width, } } }