From 43827818b1ca55369322b292e8734184881ae72a Mon Sep 17 00:00:00 2001 From: Alberto Nidasio <alberto.nidasio@skywarder.eu> Date: Thu, 16 Jan 2025 00:07:37 +0100 Subject: [PATCH] Fixed connection hovering check --- src/ui/panes/pid_drawing_tool/connections.rs | 49 +++++--------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/src/ui/panes/pid_drawing_tool/connections.rs b/src/ui/panes/pid_drawing_tool/connections.rs index 5989467..2a5020f 100644 --- a/src/ui/panes/pid_drawing_tool/connections.rs +++ b/src/ui/panes/pid_drawing_tool/connections.rs @@ -1,5 +1,5 @@ use egui::{epaint::PathStroke, Color32, Painter, Rect, Rounding, Stroke, Theme}; -use glam::Vec2; +use glam::{Mat2, Vec2}; use serde::{Deserialize, Serialize}; use crate::ui::utils::glam_to_egui; @@ -48,10 +48,7 @@ impl Connection { points.push(pid.elements[self.start].anchor_point(self.start_anchor)); // Append all midpoints - self.points_g - .iter() - .map(|p| pid.grid.grid_to_screen(*p)) - .for_each(|p| points.push(p)); + self.points_g.iter().for_each(|&p| points.push(p)); // Append end point points.push(pid.elements[self.end].anchor_point(self.end_anchor)); @@ -60,7 +57,7 @@ impl Connection { for i in 0..(points.len() - 1) { let a = points[i]; let b = points[i + 1]; - if is_hovering_segment(p_g, a, b) { + if hovers_segment(&pid.grid, p_g, a, b) { return Some(i); } } @@ -144,41 +141,19 @@ impl Connection { } } -fn distance(a: Vec2, b: Vec2) -> f32 { - ((a.x - b.x).powi(2) + (a.y - b.y).powi(2)).sqrt() -} - -/// Distance of a from the line defined by b and c -fn distance_from_line(p: Vec2, m: f32, q: f32) -> f32 { - (p.y - m * p.x - q).abs() / (1.0 + m * m).sqrt() -} - /// True if p hovers the segment defined by a and b -fn is_hovering_segment(p: Vec2, a: Vec2, b: Vec2) -> bool { - if a != b { - let midpoint = (a + b) / 2.0; - let m = (a.y - b.y) / (a.x - b.x); - - let (d1, d2) = if m == 0.0 { - ((p.y - midpoint.y).abs(), (p.x - midpoint.x).abs()) - } else if m == f32::INFINITY { - ((p.x - midpoint.x).abs(), (p.y - midpoint.y).abs()) - } else { - let q = (a.x * b.y - b.x * a.y) / (a.x - b.x); - - let m_inv = -1.0 / m; - let q_inv = midpoint.y - m_inv * midpoint.x; - - ( - distance_from_line(p, m, q), - distance_from_line(p, m_inv, q_inv), - ) - }; +fn hovers_segment(grid: &GridInfo, p_g: Vec2, a_g: Vec2, b_g: Vec2) -> bool { + if a_g != b_g { + let segment_g = b_g - a_g; + let rotm = Mat2::from_angle(-segment_g.to_angle()); - let length = distance(a, b); + // Rototranslate the point in the segment frame with a as origin + let p_s = rotm * (p_g - a_g); - d1 <= CONNECTION_LINE_THRESHOLD && d2 <= length + let y_threshold = CONNECTION_LINE_THRESHOLD / grid.size(); + 0.0 <= p_s.x && p_s.x <= segment_g.length() && p_s.y.abs() <= y_threshold } else { + // If a and b are the same point, prevent adding another false } } -- GitLab