From ac856c3ad79718bad42a0fb510e8131469090ce7 Mon Sep 17 00:00:00 2001 From: Nuhiat-Arefin Date: Tue, 20 Jan 2026 14:32:54 +0600 Subject: [PATCH 1/2] Scale thin strokes to maintain a minimum selection tolerance --- .../vector-types/src/vector/click_target.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/node-graph/libraries/vector-types/src/vector/click_target.rs b/node-graph/libraries/vector-types/src/vector/click_target.rs index 9bc1a7c50f..292ffd01cc 100644 --- a/node-graph/libraries/vector-types/src/vector/click_target.rs +++ b/node-graph/libraries/vector-types/src/vector/click_target.rs @@ -259,7 +259,18 @@ impl ClickTarget { /// Does the click target intersect the point (accounting for stroke size) pub fn intersect_point(&self, point: DVec2, layer_transform: DAffine2) -> bool { - let target_bounds = [point - DVec2::splat(self.stroke_width / 2.), point + DVec2::splat(self.stroke_width / 2.)]; + //Maintain minimum 5px viewport stroke while calculating intersection point + const MIN_VIEW : f64 = 5.0; + //scaling factor for converting to viewpoint space + let scale: f64 = layer_transform.x_axis.length().max(layer_transform.y_axis.length()); + let stroke_view : f64 = scale * self.stroke_width; + let inflated_stroke: f64 = if stroke_view < MIN_VIEW{ + MIN_VIEW/scale + } + else{ + self.stroke_width + }; + let target_bounds = [point - DVec2::splat(inflated_stroke / 2.), point + DVec2::splat(inflated_stroke / 2.)]; let intersects = |a: [DVec2; 2], b: [DVec2; 2]| a[0].x <= b[1].x && a[1].x >= b[0].x && a[0].y <= b[1].y && a[1].y >= b[0].y; // This bounding box is not very accurate as it is the axis aligned version of the transformed bounding box. However it is fast. if !self From 004165494076182e9328a8cce8482654b2cfeb67 Mon Sep 17 00:00:00 2001 From: Nuhiat-Arefin Date: Thu, 22 Jan 2026 12:22:55 +0600 Subject: [PATCH 2/2] formatted --- .../vector-types/src/vector/click_target.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/node-graph/libraries/vector-types/src/vector/click_target.rs b/node-graph/libraries/vector-types/src/vector/click_target.rs index 292ffd01cc..9884d18d0b 100644 --- a/node-graph/libraries/vector-types/src/vector/click_target.rs +++ b/node-graph/libraries/vector-types/src/vector/click_target.rs @@ -259,17 +259,14 @@ impl ClickTarget { /// Does the click target intersect the point (accounting for stroke size) pub fn intersect_point(&self, point: DVec2, layer_transform: DAffine2) -> bool { - //Maintain minimum 5px viewport stroke while calculating intersection point - const MIN_VIEW : f64 = 5.0; - //scaling factor for converting to viewpoint space - let scale: f64 = layer_transform.x_axis.length().max(layer_transform.y_axis.length()); - let stroke_view : f64 = scale * self.stroke_width; - let inflated_stroke: f64 = if stroke_view < MIN_VIEW{ - MIN_VIEW/scale - } - else{ - self.stroke_width - }; + // Maintain minimum 5px viewport stroke while calculating intersection point + let minimum_stroke: f64 = 5.; + + // Scaling factor for converting to viewpoint space + let scale: f64 = layer_transform.x_axis.length().max(layer_transform.y_axis.length()); + let viewport_stroke: f64 = scale * self.stroke_width; + let inflated_stroke: f64 = if viewport_stroke < minimum_stroke { minimum_stroke / scale } else { self.stroke_width }; + let target_bounds = [point - DVec2::splat(inflated_stroke / 2.), point + DVec2::splat(inflated_stroke / 2.)]; let intersects = |a: [DVec2; 2], b: [DVec2; 2]| a[0].x <= b[1].x && a[1].x >= b[0].x && a[0].y <= b[1].y && a[1].y >= b[0].y; // This bounding box is not very accurate as it is the axis aligned version of the transformed bounding box. However it is fast.