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

MiniLibX库3D地图转2D可视化项目像素越界问题排查

FDF项目像素越界问题排查与修复

核心问题与修复方案

1. draw_map函数数组越界及坐标初始化错误

draw_map中初始化当前点坐标时,错误使用了下一行(y+1)的Z值,当y为最后一行时会触发数组越界,同时导致起点坐标计算错误,引发后续像素越界:

// 原错误代码
scale_y = (y + 1 - data->map[y + 1][x]) * data->scale;
scale_z = data->map[y + 1][x] * data->scale;

修复后:使用当前点的Z值初始化坐标,避免越界:

// 修改后的draw_map内循环代码
scale_x = x * data->scale;
scale_y = (y - data->map[y][x]) * data->scale; // 用当前y行的Z值
scale_z = data->map[y][x] * data->scale;
init_coords(&coords, scale_x, scale_y, scale_z);
rotate_and_project(&coords, data->scale, data->offset_x, data->offset_y);
// 保存当前点作为起点,传给draw_lines_from_point
t_coords start_coords = coords;
draw_lines_from_point(data, &start_coords, x, y);

2. draw_lines_from_point函数未保留起点坐标

原代码中调用bresenham时只传入了终点坐标,缺失起点信息,导致绘制的线起点错误。需要保留起点,设置终点后再调用画线函数:

// 修改后的draw_lines_from_point函数
void    draw_lines_from_point(t_data *data, t_coords *start_coords, int x, int y) {
    t_coords end_coords;
    int scale_x;
    int scale_y;
    int scale_z;

    end_coords.angle_x = start_coords->angle_x;
    end_coords.angle_y = start_coords->angle_y;
    end_coords.angle_z = start_coords->angle_z;

    if (x < data->map_width - 1)
    {
        scale_x = (x + 1) * data->scale;
        scale_y = (y - data->map[y][x + 1]) * data->scale;
        scale_z = data->map[y][x + 1] * data->scale;
        init_coords(&end_coords, scale_x, scale_y, scale_z);
        rotate_and_project(&end_coords, data->scale, data->offset_x, data->offset_y);
        // 传递起点和终点:将start_coords的x0,y0作为起点,end_coords作为终点
        t_coords line_coords = *start_coords;
        line_coords.x1 = end_coords.x0;
        line_coords.y1 = end_coords.y0;
        draw_line_between_points(data, &line_coords);
    }
    if (y < data->map_height - 1)
    {
        scale_x = x * data->scale;
        scale_y = ((y + 1) - data->map[y + 1][x]) * data->scale;
        scale_z = data->map[y + 1][x] * data->scale;
        init_coords(&end_coords, scale_x, scale_y, scale_z);
        rotate_and_project(&end_coords, data->scale, data->offset_x, data->offset_y);
        // 传递起点和终点
        t_coords line_coords = *start_coords;
        line_coords.x1 = end_coords.x0;
        line_coords.y1 = end_coords.y0;
        draw_line_between_points(data, &line_coords);
    }
}

3. calculate_scaling_and_offset函数缩放逻辑错误

原函数使用未初始化的data->scale计算地图最大尺寸,导致缩放比例完全错误:

// 原错误代码
map_max_width = data->map_width * data->scale;
map_max_height = data->map_height * data->scale;

修复后:先基于原始网格尺寸计算缩放比例,加入等距投影修正避免地图超出窗口:

void    calculate_scaling_and_offset(t_data *data)
{
    // 原始网格的宽高(未缩放)
    double  map_max_width = data->map_width;
    double  map_max_height = data->map_height;
    // 等距投影会改变宽高比例,加入修正
    map_max_width *= cos(0.523599) * 2; // 0.523599对应30度弧度
    map_max_height *= sin(0.523599);

    double  scale_x = (double)WIN_WIDTH / map_max_width;
    double  scale_y = (double)WIN_HEIGHT / map_max_height;
    // 取最小缩放比例,保证地图能完整放入窗口
    data->scale = fmin(scale_x, scale_y);
    // 计算居中偏移
    data->offset_x = (WIN_WIDTH - (map_max_width * data->scale)) / 2;
    data->offset_y = (WIN_HEIGHT - (map_max_height * data->scale)) / 2;
}

4. get_map_dim函数宽度计算不准确

原代码通过空格数+1计算宽度,无法处理连续空格或行尾空格的情况,导致宽度计算偏大:

// 原错误代码
while (*ptr)
{
    if (*ptr == ' ')
        temp_width++;
    ptr++;
}
temp_width++;

修复后:通过分割字符的方式准确计算点数量:

void    get_map_dim(const char *file_name, int *width, int *height)
{
    int     fd;
    char    *line;
    char    *token;
    int     temp_width;

    fd = open (file_name, O_RDONLY);
    if (fd < 0)
        exit_flr (EXIT_FAILURE, "Error opening file");
    *width = 0;
    *height = 0;
    temp_width = 0;
    while ((line = get_next_line(fd)) != NULL)
    {
        temp_width = 0;
        token = ft_strtok(line, " ");
        while (token != NULL)
        {
            temp_width++;
            token = ft_strtok(NULL, " ");
        }
        if (*width < temp_width)
            *width = temp_width;
        (*height)++;
        free (line);
    }
    close (fd);
}

5. draw_map函数循环未递增变量

原代码中x和y的循环没有递增,导致无限循环,重复计算同一坐标引发错误:

// 原错误代码
y = 0;
while (y < data->map_height)
{
    x = 0;
    while (x < data->map_width)
    {
        // ... 代码 ...
    }
}

修复后:添加循环变量递增:

y = 0;
while (y < data->map_height)
{
    x = 0;
    while (x < data->map_width)
    {
        // ... 代码 ...
        x++; // 递增x
    }
    y++; // 递增y
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 18:52:01