From fc9c8c33963afeb79b7cddc8589158410fc7eb21 Mon Sep 17 00:00:00 2001 From: Alain Emilia Anna Zscheile Date: Wed, 11 Dec 2024 00:13:52 +0100 Subject: [PATCH] refactor(specctra-core/math/Circle): factor out (angle -> position) routine --- crates/specctra-core/src/math.rs | 13 +++++++++++++ crates/specctra-core/src/structure.rs | 17 +++++++++++++++++ crates/topola-egui/src/painter.rs | 15 ++++++++------- src/specctra/design.rs | 11 +++++------ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/crates/specctra-core/src/math.rs b/crates/specctra-core/src/math.rs index e098d2b..2ba94b1 100644 --- a/crates/specctra-core/src/math.rs +++ b/crates/specctra-core/src/math.rs @@ -14,6 +14,19 @@ pub struct PointWithRotation { pub rot: f64, } +impl Circle { + /// Calculate the point that lies on the circle at angle `phi`, + /// relative to coordinate axes. + /// + /// `phi` is the angle given in radians starting at `(r, 0)`. + pub fn position_at_angle(&self, phi: f64) -> Point { + geo::point! { + x: self.pos.0.x + self.r * phi.cos(), + y: self.pos.0.y + self.r * phi.sin() + } + } +} + impl Sub for Circle { type Output = Self; diff --git a/crates/specctra-core/src/structure.rs b/crates/specctra-core/src/structure.rs index 385065e..bff9112 100644 --- a/crates/specctra-core/src/structure.rs +++ b/crates/specctra-core/src/structure.rs @@ -392,6 +392,23 @@ pub struct Point { pub y: f64, } +impl From for Point { + #[inline(always)] + fn from(z: geo::Point) -> Self { + Point { x: z.0.x, y: z.0.y } + } +} + +impl From for geo::Point { + #[inline(always)] + fn from(z: Point) -> Self { + geo::point! { + x: z.x, + y: z.y + } + } +} + // Custom impl for the case described above impl ReadDsn for Vec { fn read_dsn(tokenizer: &mut ListTokenizer) -> Result { diff --git a/crates/topola-egui/src/painter.rs b/crates/topola-egui/src/painter.rs index 87f06f9..d2ff695 100644 --- a/crates/topola-egui/src/painter.rs +++ b/crates/topola-egui/src/painter.rs @@ -42,13 +42,14 @@ impl<'a> Painter<'a> { let angle_from = bend.start_angle(); let angle_step = bend.spanned_angle() / 100.0; - let mut points: Vec = vec![]; - - for i in 0..=100 { - let x = circle.pos.x() + circle.r * (angle_from + i as f64 * angle_step).cos(); - let y = circle.pos.y() + circle.r * (angle_from + i as f64 * angle_step).sin(); - points.push(self.transform.mul_pos([x as f32, -y as f32].into())); - } + let points = (0..=100) + .into_iter() + .map(|i| circle.position_at_angle(angle_from + i as f64 * angle_step)) + .map(|point| { + self.transform + .mul_pos([point.0.x as f32, -point.0.y as f32].into()) + }) + .collect(); egui::Shape::line( points, diff --git a/src/specctra/design.rs b/src/specctra/design.rs index a7f8768..952bffd 100644 --- a/src/specctra/design.rs +++ b/src/specctra/design.rs @@ -101,13 +101,12 @@ impl SpecctraDesign { (0..=segment_count) .into_iter() - .map(|i| angle_from + i as f64 * angle_step) - .map(|phi| { - let x = circle.pos.x() + circle.r * phi.cos(); - let y = circle.pos.y() + circle.r * phi.sin(); - structure::Point { x, y } + .map(|i| { + circle + .position_at_angle(angle_from + i as f64 * angle_step) + .into() }) - .collect() + .collect::>() } // Intentionally skipped for now.