mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-25 19:36:49 -06:00
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>
41 lines
1.7 KiB
Rust
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:?}");
|
|
}
|