Two object-snap fixes:
- Tangent on a circle built the snap point as
`(cx + r·nx, cy, cy + r·ny)` — the y-offset landed in Z and Y was stuck
at the centre, so the tangent point sat at the wrong place. Build it as
`(cx + r·nx, cy + r·ny, cz)`.
- Endpoint snapped to a full circle / ellipse: for tessellated curves it
snaps the first/last point, but a closed curve's first/last is a seam,
not an endpoint. Skip Endpoint for closed curves — identified by their
Quadrant snap hints, which arcs never carry — so arcs still snap their
real endpoints.
Closes#274, closes#275
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Extension-driven acquisition (OTRACK off) acquired any dwelled snap
point, including the extension foot the cursor paused on while tracing an
extension. Each such spurious acquisition filled the 4-point buffer and
evicted, oldest-first, the endpoint the user had actually acquired — so
after a few pauses its + marker and its extension disappeared.
Restrict Extension-driven acquisition to real segment endpoints (points
with an incident edge); midpoints, centres, intersections and extension
feet are ignored. OTRACK still acquires any snap point.
Refs #262
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Extension snap extended every segment's line in the whole drawing, so in
a larger project an extension foot was live almost everywhere and the
cursor snapped to it constantly.
Extension now behaves like a temporary tracking point: an endpoint must
first be acquired by dwelling on it, and only then does that segment's
line extend. Acquisition — and the tracking-point marker — is active
whenever OTRACK is on OR the Extension snap is on, so Extension works
independently of OTRACK's on/off state (and is not tied to POLAR). Both
the per-segment extension and the extended-intersection candidates are
gated on an acquired endpoint, and the whole scan is skipped when nothing
is acquired (the common case), keeping large drawings responsive.
Closes#262
Co-Authored-By: Claude Opus 4.8 <[email protected]>
#218: with Ortho on and a base point the axis is now a hard lock — a lone
tracking ray can't pull the cursor off it. Only a tracking ray crossing
the ortho axis locks (the corner-finding case); otherwise the ortho
constraint applies as the fallback, so Ortho reliably locks when OTRACK
is also on.
#219: an acquired corner now contributes an alignment ray along its own
edge direction(s) (captured once at acquisition), so OTRACK follows a
segment's extension, not just the ortho/polar axes. Acquisition is also
captured on leave — a perfectly still cursor emits no move events, so
"pause on a corner, then drag" now reliably acquires it. The acquired
marker projects through the active pane's camera + rect (canvas offset
included) instead of vanishing, and the active alignment path is drawn
as a full-length dashed guide through the corner.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Extension osnap now offers a ray off every polyline vertex, not just the
first and last, and snaps to where two segments' extension lines would
cross. That crossing is emitted as an Intersection so it outranks the
per-segment extension feet on their own lines. When it wins, both
contributing extensions are re-detected — off-ray distance measured in
screen space so the tolerance holds at UTM coordinates — and the overlay
draws a dashed guide from each endpoint through the crossing, so both
extension paths remain visible instead of vanishing when caught.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The Extension object snap worked but drew no tracking path, so it was
easy to miss — users had to keep the cursor exactly on the invisible
extension line without any visual cue.
When an Extension snap is active, draw a dashed guide line from the
endpoint it extends from, through the snap point and a little beyond,
and orient the three-dot marker along that direction. SnapResult carries
the endpoint screen position (filled once the winning snap is known);
the overlay renders the guide.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- Delete src/modules/draw/modify/extend.rs (a 1-line placeholder with no
tool()/logic; `extend::` was referenced nowhere) and its `mod extend;`.
- Flatten single-file module dirs to the modern flat style:
src/command/mod.rs -> src/command.rs, src/snap/mod.rs -> src/snap.rs.
Parent `mod command;`/`mod snap;` are unchanged.
Co-Authored-By: Claude Opus 4.8 <[email protected]>