From 391fda6206c98c330bf677eb3591b3b0b3b5b56b Mon Sep 17 00:00:00 2001 From: Mitchell Hansen Date: Wed, 6 May 2026 23:36:33 -0700 Subject: [PATCH] brush-paint: collapse would_be_stuck + min_score termination Walker had two stop conditions that did the same job differently: - score < min_score: best direction's lookahead is below threshold - would_be_stuck: current disk and next-step disk both have 0 new ink (so even a perfect direction wouldn't add coverage) The discrete would_be_stuck check fires more aggressively, killing the walker at k=0/k=1 even when the lookahead horizon (k=2,3) sees unpainted ink that the walker could reach in one more step. With the Dijkstra repaint gone (prev commit), this just means strokes end one step earlier than they need to. Removed the would_be_stuck branch. Walker now stops cleanly when score < min_score; lookahead's 1/k weighting handles the "distant ink" case naturally. Side effect: alphabet report's worst scale (3mm/150) went from 82% coverage to 94%. polish + would_be_stuck were both hurting small fonts (where painted-disk overlap is heavy and the discrete check fired constantly). Other scales unchanged. --- src/brush_paint.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/brush_paint.rs b/src/brush_paint.rs index 633e58c2..d4d02489 100644 --- a/src/brush_paint.rs +++ b/src/brush_paint.rs @@ -894,16 +894,8 @@ fn walk_brush(start: (f32, f32), init_dir: Option<(f32, f32)>, } }; - // Stuck check: would we land on already-painted ink AND are we - // sitting on already-painted ink? - let would_be_stuck = { - let new_p_probe = (p.0 + dir.0 * step_size, p.1 + dir.1 * step_size); - let (nc, _, _) = grid.evaluate_disk(new_p_probe, brush_radius); - nc == 0 && grid.evaluate_disk(p, brush_radius).0 == 0 - }; - - if score < min_score || would_be_stuck { - exit_reason = if score < min_score { "score_below_min".into() } else { "stuck".into() }; + if score < min_score { + exit_reason = "score_below_min".into(); if let Some(t) = trace.as_deref_mut() { t.steps.push(WalkStep { idx: step_idx, p, prev_dir, @@ -913,9 +905,8 @@ fn walk_brush(start: (f32, f32), init_dir: Option<(f32, f32)>, } break; } - let chosen_dir = dir; - let new_p = (p.0 + chosen_dir.0 * step_size, p.1 + chosen_dir.1 * step_size); + let new_p = (p.0 + dir.0 * step_size, p.1 + dir.1 * step_size); if let Some(t) = trace.as_deref_mut() { t.steps.push(WalkStep { @@ -928,7 +919,7 @@ fn walk_brush(start: (f32, f32), init_dir: Option<(f32, f32)>, p = new_p; path.push(p); - prev_dir = Some(chosen_dir); + prev_dir = Some(dir); grid.paint_disk(p, brush_radius); step_idx += 1; }