From 90fd0f592fd05f878f2edc5b88620f8b3717eb71 Mon Sep 17 00:00:00 2001 From: Heller Date: Fri, 19 Jun 2026 10:27:42 +0000 Subject: [PATCH] fix: virtual grid-snapped tail anchor prevents corner diagonals MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Body path now goes: interp_tail → grid_tail → segment[N-2] → ... → head. The short leg from interpolated to grid-snapped tail is always straight (same direction), and from grid_tail onward the path strictly follows the grid — preserving sharp corners while tail stays smooth. --- Snake.Avalonia/Views/SnakeRenderer.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Snake.Avalonia/Views/SnakeRenderer.cs b/Snake.Avalonia/Views/SnakeRenderer.cs index b5b6598..f6ae1f8 100644 --- a/Snake.Avalonia/Views/SnakeRenderer.cs +++ b/Snake.Avalonia/Views/SnakeRenderer.cs @@ -135,18 +135,23 @@ public sealed class SnakeRenderer : Control var segmentsList = Segments; var count = segmentsList.Count; - // === Body path: from segment[Count-1] (tail) through segment[0] (head) === - // All segments use GetVisualPosition — middle/body returns grid-snapped, - // head returns interpolated. Tail is grid-snapped, giving sharp corners - // with full body thickness. + // === Body path: from interp tail → grid tail (virtual corner anchor) → body → head === + // The virtual grid-snapped tail prevents diagonal shortcuts at corners: + // the short leg from interp_tail to grid_tail is always straight (same direction), + // and from grid_tail onward the path strictly follows the grid. if (count >= 2) { var bodyGeometry = new StreamGeometry(); using (var ctx = bodyGeometry.Open()) { - // Start at tail (last segment, grid-snapped) - var (startX, startY) = GetVisualPosition(segmentsList[count - 1], count - 1, t); - ctx.BeginFigure(new Point(startX, startY), false); + // Start at interpolated tail + var (tailX, tailY) = GetVisualPosition(segmentsList[count - 1], count - 1, t); + ctx.BeginFigure(new Point(tailX, tailY), false); + + // Virtual corner anchor: grid-snapped tail position + var lastPos = segmentsList[count - 1]; + var (gridTailX, gridTailY) = (lastPos.X * CellSize + CellSize * 0.5, lastPos.Y * CellSize + CellSize * 0.5); + ctx.LineTo(new Point(gridTailX, gridTailY)); // Draw through middle segments down to head for (var i = count - 2; i >= 0; i--)