mell stefanova
mell stefanova

Reputation: 11

problem with MiniLibX library project for visualization of 3d maps into 2d

So this is my code without the key_event and mlx initiation. I guess the main problem is that I first tried to make it dynamic and get the size for the map from the file but then I realized that this size is changing and then I rewrote the code with a fixed window but I guess I forgot something and everything go to hell...

int main(int ac, char **av)
{
    t_data  data;

    if (ac != 2)
    {
        ft_printf ("use an fdf map");
        return (EXIT_FAILURE);
    }
    get_map_dim (av[1], &data.map_width, &data.map_height);
    data.map = allocate_map(data.map_width, data.map_height);
    parse_fdf_file (&data, av[1]);
    data.win_width = WIN_WIDTH;
    data.win_height = WIN_HEIGHT;
    data.rot_angle_x = 0;
    data.rot_angle_y = 0;
    data.rot_angle_z = 0;
    calculate_scaling_and_offset(&data);
    if (init_mlx (&data) == EXIT_FAILURE)
        return (EXIT_FAILURE);
    draw_map (&data);
    mlx_key_hook (data.win_ptr, handle_keypress, &data);
    mlx_loop (data.mlx_ptr);
    return (EXIT_SUCCESS);
}

void    draw_pixel(t_data *data, int x, int y, int color)
{
    if (x >= 0 && x < data->win_width && y >= 0 && y < data->win_height)
        mlx_pixel_put (data->mlx_ptr, data->win_ptr, x, y, color);
    else
        ft_printf ("pixel out of bounds: x = %d, y = %d\n", x, y);
}

void    init_bresenham(t_coords *coords, t_bresenham *bres)
{
    bres->dx = fabs(coords->x1 - coords->x0);
    bres->dy = fabs(coords->y1 - coords->y0);
    if (coords->x0 < coords->x1)
        bres->sx = 1;
    else
        bres->sx = -1;
    if (coords->y0 < coords->y1)
        bres->sy = 1;
    else
        bres->sy = -1;
    bres->err = bres->dx - bres->dy;
}

void    draw_line(t_data *data, t_coords *coords, t_bresenham *bres)
{
    while (1)
    {
        draw_pixel (data, coords->x0, coords->y0, 0xFFFFFF);
        if (coords->x0 == coords->x1 && coords->y0 == coords->y1)
            break;
        bres->e2 = 2 *bres->err;
        if (bres->e2 > -bres->dy)
        {
            bres->err -= bres->dy;
            coords->x0 += bres->sx;
        }
        if (bres->e2 < bres->dx)
        {
            bres->err += bres->dx;
            coords->y0 += bres->sy;
        }
    }
}

void bresenham(t_data *data, t_coords *coords)
{
    t_bresenham bres;
    
    init_bresenham(coords, &bres);
    draw_line(data, coords, &bres);
}

void isometric_prj(t_coords *coords)
{
    double prev_x;
    double prev_y;
    double prev_z;
    double iso_x;
    double iso_y;

    prev_x = coords->x0;
    prev_y = coords->y0;
    prev_z = coords->z0;
    coords->y0 = prev_y * cos(coords->angle_x) - prev_z * sin(coords->angle_x);  // Rotate around X-axis
    coords->z0 = prev_y * sin(coords->angle_x) + prev_z * cos(coords->angle_x);
    prev_x = coords->x0; // Rotate around Y-axis
    prev_z = coords->z0;
    coords->x0 = prev_x * cos(coords->angle_y) + prev_z * sin(coords->angle_y);
    coords->z0 = -prev_x * sin(coords->angle_y) + prev_z * cos(coords->angle_y);
    prev_x = coords->x0;     // Rotate around Z-axis
    prev_y = coords->y0;
    coords->x0 = prev_x * cos(coords->angle_z) - prev_y * sin(coords->angle_z);
    coords->y0 = prev_x * sin(coords->angle_z) + prev_y * cos(coords->angle_z);
    iso_x = (coords->x0 - coords->y0) * cos(0.523599);   // Isometric projection
    iso_y = coords->z0 + (coords->x0 + coords->y0) * sin(0.523599);
    coords->x0 = iso_x;
    coords->y0 = iso_y;
}

void    init_coords(t_coords *coords, int scale_x, int scale_y, int scale_z) {
    coords->x0 = scale_x;
    coords->y0 = scale_y;
    coords->z0 = scale_z;
}

void    rotate_and_project(t_coords *coords, double scale, int offset_x, int offset_y)
{
    isometric_prj(coords);
    coords->x0 = coords->x0 * scale;
    coords->y0 = coords->y0 * scale;
    coords->x0 = (int)(coords->x0 + offset_x);
    coords->y0 = (int)(coords->y0 + offset_y);
}

void draw_line_between_points(t_data *data, t_coords *coords) 
{
    bresenham(data, coords);
}

void    draw_lines_from_point(t_data *data, t_coords *coords, int x, int y) {
    int scale_x;
    int scale_y;
    int scale_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(coords, scale_x, scale_y, scale_z);
        rotate_and_project(coords, data->scale, data->offset_x, data->offset_y);
        draw_line_between_points(data, 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(coords, scale_x, scale_y, scale_z);
        rotate_and_project(coords, data->scale, data->offset_x, data->offset_y);
        draw_line_between_points(data, coords);
    }
}

void    draw_map(t_data *data)
{
    t_coords    coords;
    int         x;
    int         y;
    int         scale_x;
    int         scale_y;
    int         scale_z;

    coords.angle_x = data->rot_angle_x;
    coords.angle_y = data->rot_angle_y;
    coords.angle_z = data->rot_angle_z;
    y = 0;
    while (y < data->map_height)
    {
        x = 0;
        while (x < data->map_width)
        {
            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(&coords, scale_x, scale_y, scale_z);
            rotate_and_project(&coords, data->scale, data->offset_x, data->offset_y);
            draw_lines_from_point(data, &coords, x, y);
        }
    }
}

void    exit_flr(int exit_code, const char *err_msg)
{
    perror (err_msg);
    exit (exit_code);
}

void    get_map_dim(const char *file_name, int *width, int *height)
{
    int     fd;
    char    *line;
    char    *ptr;
    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;
        ptr = line;
        while (*ptr)
        {
            if (*ptr == ' ')
                temp_width++;
            ptr++;
        }
        temp_width++;
        if (*width < temp_width)
            *width = temp_width;
        (*height)++;
        free (line);
    }
    close (fd);
}

int **allocate_map(int width, int height)
{
    int **map;
    int i;

    map = (int **)malloc(height * sizeof(int *));
    if (!map)
        exit_flr (EXIT_FAILURE, "Error allocating memory for map");
    i = 0;
    while (i < height)
    {
        map[i] = (int *)malloc(width * sizeof(int));
        if (!map[i])
            exit_flr (EXIT_FAILURE, "Error allocating memory for map row");
        i++;
    }
    return (map);
}

void    parse_fdf_file(t_data *data, const char *file_name)
{
    int     fd;
    char    *line;
    char    *token;
    int     x;
    int     y;

    fd = open (file_name, O_RDONLY);
    if (fd < 0)
        exit_flr (EXIT_FAILURE, "Error opening file");
    y = 0;
    while ((line = get_next_line(fd)) != NULL)
    {
        x = 0;
        token = ft_strtok (line, " ");
        while (token != NULL)
        {
            data->map[y][x] = ft_atoi (token);
            token = ft_strtok (NULL, " ");
            x++;
        }
        free (line);
        y++;
    }
    close (fd);
}

void    calculate_scaling_and_offset(t_data *data)
{
    int     map_max_width;
    int     map_max_height;
    double  scale_x;
    double  scale_y;

    map_max_width = data->map_width * data->scale;
    map_max_height = data->map_height * data->scale;
    scale_x = (double)WIN_WIDTH / (double)map_max_width;
    scale_y = (double)WIN_HEIGHT / (double)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;
}

After compiling this code in C when I try to open a map, it just shows that it's trying to draw pixels out of bounds. I guess it's a stupid mistake but I'm stuck on this for over 6 days and I kind of stopped..

Upvotes: 1

Views: 48

Answers (0)

Related Questions