forked from 1b-agent/opencadstudio-upstream
fix(snap): correct snap symbols + drop bogus midpoints on circles (#34)
Two bugs from #34: 1. Hovering a circle showed the Center snap as a diamond instead of the conventional circle outline. 2. Hovering a circle also showed Midpoint hits (triangle marker) even though a closed curve has no midpoint. (2) came from a "tessellated curve" fallback in the Midpoint snap path that produced a midpoint for every chord of the polyline approximation. Drop that fallback — only entities with explicit `key_vertices` (Line, LwPolyline) contribute per-segment midpoints now. Curves that DO have a single well-defined midpoint (arcs, and later splines) declare it explicitly via a new `SnapHint::Midpoint`; `arc.rs` emits one at the arc-length centre. (1) — and the broader "everything past Endpoint / Midpoint / Grid was a diamond" inconsistency — fixed by giving every `SnapType` a distinct marker in `SelectionCanvas::draw`: - Center: hollow circle - Node: circle with inscribed X - Quadrant: diamond (unchanged) - Intersection: X - Apparent Intersection: X inside a square - Insertion: two overlapping rectangles (tag glyph) - Perpendicular: right-angle hook - Tangent: circle with a bar across the top - Nearest: hourglass / bowtie - Extension: three dots - Parallel: two parallel diagonal bars - Endpoint / Midpoint / Grid: unchanged Closes #34
This commit is contained in:
1 parent
89fcb21b46
commit
0ec6d77cb1
4 files changed
+162
-28
No files matched your search
+6
-11
@@ -334,6 +334,7 @@ impl Snapper {
|
||||
SnapHint::Node => SnapType::Node,
|
||||
SnapHint::Quadrant => SnapType::Quadrant,
|
||||
SnapHint::Insertion => SnapType::Insertion,
|
||||
SnapHint::Midpoint => SnapType::Midpoint,
|
||||
};
|
||||
if self.is_on(snap_type) {
|
||||
try_pt(world, snap_type);
|
||||
@@ -367,13 +368,17 @@ impl Snapper {
|
||||
}
|
||||
|
||||
// ── Midpoint ───────────────────────────────────────────────────────
|
||||
// Only explicit vertex sets (Line, LwPolyline) contribute per-segment
|
||||
// midpoints. Tessellated curves (Circle, Arc, Ellipse, Spline) emit a
|
||||
// single `SnapHint::Midpoint` snap_pt where one exists — iterating
|
||||
// every chord here would otherwise turn a circle's tessellation into
|
||||
// a haze of false midpoint hits. See #34.
|
||||
if self.is_on(SnapType::Midpoint) {
|
||||
for wire in wires {
|
||||
if !wire_in_range(wire) {
|
||||
continue;
|
||||
}
|
||||
if !wire.key_vertices.is_empty() {
|
||||
// Use explicit vertices for accurate per-segment midpoints.
|
||||
for seg in wire.key_vertices.windows(2) {
|
||||
let a = Vec3::from(seg[0]);
|
||||
let b = Vec3::from(seg[1]);
|
||||
@@ -381,16 +386,6 @@ impl Snapper {
|
||||
try_pt((a + b) * 0.5, SnapType::Midpoint);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Tessellated curves: midpoint of whole arc (first↔last midpoint skipped
|
||||
// for closed curves; arcs use their own quadrant snaps instead).
|
||||
for seg in wire.points.windows(2) {
|
||||
let a = Vec3::from(seg[0]);
|
||||
let b = Vec3::from(seg[1]);
|
||||
if a.distance_squared(b) > 1e-12 {
|
||||
try_pt((a + b) * 0.5, SnapType::Midpoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user