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
相关产品推荐
相关产品推荐

