From 82d33e27df70d1844890d793eed8ea3b0a2b41bb Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Sun, 17 May 2026 18:56:04 +0800 Subject: [PATCH] fix(canvas): arc-sector hit-test handles a negative sweep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A negative `sweep_angle` covers the angular range `[start + sweep, start]`; the hit-test compared against `sweep.abs()` from `start`, rejecting points that are actually inside such an arc. Normalise to a forward sweep before the angle-window test. Self-review follow-up to the arc/pen-handle work (the codex second review stalled mid-run). op-editor-ui 148 tests green. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- crates/op-editor-ui/src/layout_scene_hit.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/op-editor-ui/src/layout_scene_hit.rs b/crates/op-editor-ui/src/layout_scene_hit.rs index 036b9418c..ccb4e0bc1 100644 --- a/crates/op-editor-ui/src/layout_scene_hit.rs +++ b/crates/op-editor-ui/src/layout_scene_hit.rs @@ -191,10 +191,16 @@ fn point_in_node(node: &SceneNode, local: Point2D, bounds: Rect, zoom: f32) -> b let sweep = node.arc_sweep_angle.unwrap_or(360.0); if sweep.abs() < 359.9 { let start = node.arc_start_angle.unwrap_or(0.0); - // Angle of the point, normalised into [0, sweep). + // Normalise to a forward sweep — a negative sweep + // covers the angular range `[start + sweep, start]`. + let (sector_start, span) = if sweep < 0.0 { + (start + sweep, -sweep) + } else { + (start, sweep) + }; let ang = dy.atan2(dx).to_degrees(); - let rel = (ang - start).rem_euclid(360.0); - if rel > sweep.abs() { + let rel = (ang - sector_start).rem_euclid(360.0); + if rel > span { return false; } }