Skip to content

[Detail Bug] Sorting animation logo shows holes during Idle/Sorting due to incorrect region check #268

@detail-app

Description

@detail-app

Detail Bug Report

https://app.detail.dev/org_5f375fe3-a706-4e9a-a6f7-800f2439b3f6/bugs/bug_85d5ca30-433d-43d9-9ffd-5e80c7d4e8aa

Introduced in #118 by @sachiniyer on Feb 25, 2026

Summary

  • Context: The pixel_style_at function in render.rs determines the visual style (Off/Base/Active/Complete) for each pixel in a triangle-based logo visualization for a sorting animation.
  • Bug: The source_region != region check at lines 210-211 incorrectly turns off pixels that are inside a triangle, creating visible "holes" during Idle and Sorting phases.
  • Actual vs. expected:
    • Actual (without fix):
      • Idle: 27.7% pixels invisible (holes)
      • Sorting: Same holes persist (no change!)
      • Completion: Holes disappear (but only because source_x ≈ local_x)
    • Expected (with fix):
      • Idle: All triangle pixels visible as Base
      • Sorting: Blue Active sweep progresses, pixels turn Complete behind it
      • Completion: All pixels Complete, then cycle resets
  • Impact: 27.7% of triangle pixels are incorrectly turned off in Idle/Sorting phases.

Code with Bug

let source_x = source_local_x_for_index(shuffled_idx, ctx.n, region, ctx.viewport_width);
let source_region = logo_region_at(source_x, local_y, ctx.viewport_width, ctx.viewport_height);
if source_region != region { // <-- BUG 🔴 mixes 1D `source_x` with 2D `local_y`, hiding valid triangle pixels
    return PixelStyle::Off;
}
let shuffled_idx = visual_source_index_for_nominal(ctx.state, nominal_index, ctx.n);  // ONLY used for:
let source_x = source_local_x_for_index(shuffled_idx, ctx.n, region, ctx.viewport_width);
// ... source_region check ...
// Then style uses nominal_index, NOT shuffled_idx:
return match ctx.state.style_for_index_with_min_window(nominal_index, ctx.active_min_window) {

Explanation

The animation visualizes a 1D array where indices map to X coordinates; array elements have no Y coordinate. The source_region check computes a source_x from a shuffled 1D index and then calls logo_region_at(source_x, local_y, ...), combining that source_x with the current pixel’s local_y. This has no semantic meaning and causes many pixels that are inside a triangle to be incorrectly treated as outside, producing static “holes” during both Idle and Sorting phases.

The holes disappear in the completion phase not because the sort “fixed” anything in this check, but because visual_source_index_for_nominal returns nominal_index when the scan is complete, making source_x ≈ local_x and therefore source_region == region.

Codebase Inconsistency

shuffled_idx is not used to place pixels or determine color/style; the renderer ultimately styles pixels based on nominal_index via style_for_index_with_min_window(...). This makes the source_region gate effectively dead/incorrect logic that only removes pixels.

Recommended Fix

fn pixel_style_at(ctx: &PixelQueryCtx<'_>, local_x: usize, local_y: usize) -> PixelStyle {
    let region = logo_region_at(local_x, local_y, ctx.viewport_width, ctx.viewport_height);
    if region == LogoRegion::Empty {
        return PixelStyle::Off;
    }

    if matches!(region, LogoRegion::TopTriangle | LogoRegion::BottomTriangle) {
        let nx = usize_to_f32(local_x) / ctx.x_den;
        let nominal_index = triangle_nominal_index(nx, ctx.n, region);
        // Remove: shuffled_index, source_x, source_region check (unused for styling)
        return match ctx
            .state
            .style_for_index_with_min_window(nominal_index, ctx.active_min_window)
        {
            BandStyle::Idle => PixelStyle::Base,
            BandStyle::Active => PixelStyle::Active,
            BandStyle::Complete => PixelStyle::Complete,
        };
    }

    PixelStyle::Base
}

History

This bug was introduced in commit e4806b8. The commit created the entire satisfying_sort module from scratch, implementing a terminal animation for visualizing array sorting. The source_region != region check was included in the initial pixel_style_at implementation, likely intended to validate that pixels were being rendered for elements still "in place" within their triangle region. However, the check incorrectly combined source_x (computed from a 1D shuffled array index) with local_y (a 2D display coordinate) — coordinates that have no semantic relationship since array elements have no Y-coordinate. This geometric inconsistency caused 27.7% of triangle pixels to be incorrectly hidden during Idle and Sorting phases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions