Files
cadcraft/crates/engine/tests/snap_nearest.rs
Valentin KleinandClaude Opus 5.5 049504a81e Nearest snap picks the closest object in any drawing order (fixes #323) (#324)
A circle in the aperture replaced the best Nearest candidate without
comparing distances, so a closer line drawn earlier lost to it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:54:42 -04:00

41 lines
1.7 KiB
Rust

//! Nearest (NEA) object snap picks the closest point of all objects in the aperture, whatever
//! order they were drawn in.
use cadcraft_engine::Session;
use cadcraft_engine::doc::Space;
use cadcraft_engine::geom::Vec2;
use cadcraft_engine::snap::{self, mode};
use serde_json::json;
fn nearest(s: &Session, cursor: Vec2) -> Vec2 {
let hit = snap::osnap(s.doc().unwrap(), &Space::Model, cursor, 1.0, mode::NEA, None, false).expect("a nearest snap");
assert_eq!(hit.mode, mode::NEA);
hit.point
}
#[test]
fn nearest_prefers_the_closer_object_in_any_drawing_order() {
// A line along y = 0 and a circle whose edge passes y = 0.8 above the cursor at (0, 0.1):
// the line (0.1 away) is closer than the circle (0.7 away).
for circle_first in [false, true] {
let mut s = Session::new();
let line = || json!({ "points": [[-5, 0], [5, 0]] });
let circle = || json!({ "center": [0, 3.8], "radius": 3 });
if circle_first {
s.execute("circle", &circle()).unwrap();
s.execute("line", &line()).unwrap();
} else {
s.execute("line", &line()).unwrap();
s.execute("circle", &circle()).unwrap();
}
let p = nearest(&s, Vec2::new(0.0, 0.1));
assert!(p.near(Vec2::new(0.0, 0.0), 1e-6), "circle drawn first: {circle_first}: snapped to {p:?}");
}
// And the circle wins where it is the closer one.
let mut s = Session::new();
s.execute("circle", &json!({ "center": [0, 3.8], "radius": 3 })).unwrap();
s.execute("line", &json!({ "points": [[-5, 0], [5, 0]] })).unwrap();
let p = nearest(&s, Vec2::new(0.0, 0.7));
assert!(p.near(Vec2::new(0.0, 0.8), 1e-6), "snapped to {p:?}");
}