* fix(snap): keep an arc's sweep for TAN, PER and deferred snaps
An arc was snapped as its full circle: TAN and PER solutions on the circle
that fall outside the arc's sweep were offered as if they touched the arc,
and a deferred tangent lost the sweep when it was stored.
- SnapCurve gains an Arc variant carrying start and end, so a deferred snap
keeps the sweep and resolves onto the arc.
- TAN and PER filter their solutions with Arc::contains_angle; PER clamps to
the arc with Arc::closest instead of the circle's closest point.
- Tangents and perpendiculars between two deferred snaps are filtered on
both ends.
- The viewport projection maps the new variant.
- Tests: a tangent in the gap is not offered, the perpendicular clamps to an
end, and a deferred tangent keeps its sweep and solves onto the arc.
Fixes#1697
* fix(snap): correct direct PER, support Arc in deferred pairs
Addresses the review on #1698:
- Direct PER on an arc used `arc.closest(bp)`, which clamps a gap solution to an
end and misses the valid opposite antipode; both antipodes are now offered,
filtered to the arc's sweep.
- `deferred_pairs` matched only circles and lines, so any deferred pair with an
arc operand fell through to None. An arc is now matched as its carrier circle
for the math, with the sweep filter still applied to the solutions.
- Tests: the direct PER case now expects the antipode on the arc, and a
TAN-TAN pair between an arc and a circle only keeps the tangent on the arc.
* test(snap): use a margin over the boundary in the arc PER test
Addresses the review on #1698: the cursor is 5 units from the antipode, so the
aperture is 5.5 rather than 5.0 to keep the distance comparison off the
boundary; the comment now describes the antipode rather than the nearest end.
* cargo fmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
At a point prompt with a base point, holding Shift turns ortho on when
ORTHOMODE is off and off when it is on; releasing it restores the setting.
ORTHOMODE itself is never changed. While the override turns ortho on, polar
tracking is off, as with ortho on.
The UI already passed the Shift state to Session::snap_cursor (for POLARMODE
bit 8's Shift to acquire), so the change is in the engine only: snap_cursor
applies the override to its copy of the settings. Window corners (ZOOM
Window) and prompts without a base point are unaffected.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Resting the cursor on a snap point acquires it for tracking (seven at
most; resting again releases it). Acquired points send horizontal and
vertical alignment paths, or every polar angle with POLARMODE 2; the
cursor snaps where two paths cross, where a path crosses an object, or
onto the nearest path. EXT runs a line or arc on from an acquired end,
PAR gives a path parallel to a rested-on line through the base point,
APP snaps where objects would meet if extended. Direct distance entry
follows the path the cursor is on. POLARMODE is now AutoCAD's bitcode;
POLARADDANG and AUTOSNAP are new.
The engine owns all of it (Session::snap_cursor, snap/tracking.rs); the
canvas draws the + markers, dotted paths and tooltip.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Midpoint snaps halfway along the length of an elliptical arc or open spline.
Perpendicular and Tangent from a base point find every foot point and
tangent point on ellipses, elliptical arcs and splines (the one nearest the
cursor wins, as for circles): tangents to an ellipse exactly through the unit
circle, the rest by sampling the parameter range and bisecting each sign
change, with fixed iteration bounds. Quadrant on an elliptical arc offers only
the quadrant points the arc passes through.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>