You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算网格缩放后一维像素缓冲区的行主序索引?

解决Rust+minifb生命游戏中像素缓冲区索引计算问题

minifb的update_with_buffer要求的一维缓冲区是行优先存储——也就是先按顺序存完屏幕第一行的所有像素,再存第二行,以此类推。要正确计算每个放大后像素的索引,得先明确每个网格单元对应屏幕上的位置,再套用行优先的索引公式。

正确的索引计算逻辑

  1. 原网格中坐标为(y, x)的单元格,放大后对应屏幕上一个horiz_scale × vert_scale的方块:
    • 方块左上角的屏幕X坐标:x * horiz_scale
    • 方块左上角的屏幕Y坐标:y * vert_scale
  2. 方块内的偏移量px(水平方向,0到horiz_scale-1)和py(垂直方向,0到vert_scale-1),对应屏幕上的实际坐标:
    • 实际屏幕X:x * horiz_scale + px
    • 实际屏幕Y:y * vert_scale + py
  3. 行优先的索引公式:实际屏幕Y × 屏幕总宽度 + 实际屏幕X,其中屏幕总宽度是cols * horiz_scale(列数×水平缩放比例)。

修正后的代码

// 先计算屏幕总宽度,避免重复计算
let screen_width = cols * horiz_scale;
// 确保缓冲区长度是 screen_width * (rows * vert_scale),否则会索引越界

for y in 0..rows {
    for x in 0..cols {
        let color = if grid[y][x] == 1 { 0xFFFFFF } else { 0x000000 };
        for py in 0..vert_scale {
            for px in 0..horiz_scale {
                // 正确的索引计算
                let pixel_id = (y * vert_scale + py) * screen_width + (x * horiz_scale + px);
                buffer[pixel_id] = color;
            }
        }
    }
}

分析你之前的错误写法

  • 能生成方块但逻辑错误的写法:y * cols as usize * horiz_scale + x * vert_scale * rows + px * py
    这里x * vert_scale * rows完全混淆了行和列的缩放关系,px * py也不是正确的偏移计算,只是碰巧能渲染出方块,但网格的位置、缩放比例肯定不符合预期。
  • 导致闪烁的写法:x * rows as usize * vert_scale * horiz_scale + y * vert_scale * horiz_scale + px * vert_scale + py
    这个公式把x作为行维度计算,相当于把图像旋转了90度,而且大概率会计算出超出缓冲区范围的索引,触发内存越界,进而导致窗口闪烁、显示乱码。
  • 接近正确的写法:((y * vert_scale + py) * (cols as usize * horiz_scale)+ x * horiz_scale+ px) as usize
    这个公式本身是对的,如果还是有问题,检查两点:
    1. 缓冲区的长度是否等于rows * vert_scale * cols * horiz_scale
    2. rows、cols的类型是否为usize(避免整数溢出或类型转换错误)

内容的提问来源于stack exchange,提问作者Daselsdis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:50:10