feat(draw): LINE deferred tangent — a line tangent to two circles
A line whose FIRST point is a Tangent snap on a circle can't be fixed until its direction is known, and a line tangent to TWO circles is their common tangent — neither is resolvable at a single pick. A plain LINE dropped the tangent object, so it drew a wrong line (TAN-TAN between two circles). Add an opt-in on_point_with_tangent hook (default ignores the tangent, so every other command is byte-for-byte unchanged) and route the running Tangent object through the point commit. LINE defers a first-point circle tangent and resolves it on the next pick: against a second circle tangent it picks the common tangent of the two circles (up to four — chosen by the two cursor hits, so hovering selects inner/outer + side); against a plain point it draws the tangent from that point to the circle. last_point syncs to the resolved anchor. Common-tangent and point-tangent math is f64 with perpendicularity unit tests. Refs #274 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
2da21146c4
commit
e366e47b05
3 changed files with 223 additions and 4 deletions
|
|
@ -2020,10 +2020,30 @@ pub(super) fn on_tick(&mut self, t: Instant) -> Task<Message> {
|
|||
self.dyn_user_reshaped = false;
|
||||
self.sync_dyn_fields();
|
||||
self.reset_tracking_after_point();
|
||||
self.tabs[i]
|
||||
// A running Tangent snap may carry a tangent object; a
|
||||
// command can consume it to resolve a deferred tangent
|
||||
// (LINE tangent to two circles, which needs both). When
|
||||
// it does, sync last_point to the command's resolved
|
||||
// anchor since it replaced the picked coordinate.
|
||||
let handled = self.tabs[i]
|
||||
.active_cmd
|
||||
.as_mut()
|
||||
.map(|c| c.on_point(world_pt))
|
||||
.and_then(|c| c.on_point_with_tangent(world_pt, tangent_obj_at_click));
|
||||
if handled.is_some() {
|
||||
if let Some(a) = self.tabs[i]
|
||||
.active_cmd
|
||||
.as_ref()
|
||||
.and_then(|c| c.resolved_anchor())
|
||||
{
|
||||
self.last_point = Some(a.as_vec3());
|
||||
}
|
||||
handled
|
||||
} else {
|
||||
self.tabs[i]
|
||||
.active_cmd
|
||||
.as_mut()
|
||||
.map(|c| c.on_point(world_pt))
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(r) = result {
|
||||
|
|
|
|||
Loading…
Reference in a new issue