如何制作能形成完整弧线的视野?尝试创建射线弧

问题描述 投票:0回答:1

我正在尝试使用播放器(实心圆)创建2d地图,并且我开始创建光线投射。在进行光线投射之前,我试图绘制一个简单的FOV(视场),它应该是带有实心红色的弧形圆角,如下所示:

enter image description here

(图像仅是给出了实心红色实心圆弧的概念)

为了计算图形的弧线,我得到了弧线的第一个位置:

rayAngle = rotationAngle - (FOV_ANGLE /2)

rotationAngle是播放器的弧度起始位置:

90d - PI/2
270d = 3 * PI/2
180d = PI
360d = 2 * PI

FOV_ANGLE在弧度中为60d,这是我使用此函数完成的:

60 * (PI /180)

对于其他射线,我使用这些calc:

ray_angle += fov_angle / num_ray;

num_ray只是窗口的宽度,在这种情况下,请考虑为(11 * 32)

使用此功能。我计算每条射线并保存在数组中

t_point *rays

对于结构t_point,我有这个:

typedef struct s_point
{
    int x;
    int y;
    int color;
} t_point;

[之后,我得到数组的每个索引并使用dda算法绘制一条线:

#define ROUND(a) ((int)(a + 0.5))

void ft_line_dda(t_data *img, t_point start, t_point end)
{
    int dx = end.x - start.x;
    int dy = end.y - start.y;
    int steps;
    int k;
    long double xincrement;
    long double yincrement;
    long double x = start.x;
    long double y = start.y;

    if (abs(dx) > abs(dy))
        steps = abs(dx);
    else
        steps = abs(dy);

    xincrement = abs(dx) / (long double)steps;
    yincrement = abs(dy) / (long double)steps;
    my_mlx_pixel_put(img, ROUND(x), ROUND(y), get_color(ft_create_point(ROUND(x), ROUND(y), 0), start, end));
    for (k = 0; k < steps; k++)
    {
        if (start.x <= end.x)
            x += xincrement;
        else
            x -= xincrement;
        if (start.y <= end.y)
            y += yincrement;
        else
            y -= yincrement;
        // my_mlx_pixel_put(img, ROUND(x), ROUND(y), start.color);
        my_mlx_pixel_put(img, ROUND(x), ROUND(y), get_color(ft_create_point(ROUND(x), ROUND(y), 0), start, end));
    }
}

但是问题是我不断得到带有一些点和空格的图像:

enter image description here

(大小可以。问题是空白和点)

请在下面找到与我要执行的弧(​​伪射线投射)相关的代码:

void ft_create_rays(t_vars *vars)
{
    long double fov_angle;
    long double ray_angle;
    long double num_ray;
    t_point *rays;
    int i;

    i = 0;
    fov_angle = ft_degtorad(FOV_ANGLE);
    num_ray = vars->win_width / WALL_STRIP_WIDTH;
    ray_angle = vars->player->rotation_angle - (fov_angle / 2);
    rays = malloc(num_ray * sizeof(t_point));
    while (i < num_ray)
    {
        rays[i] = ft_create_point(vars->player->x + cos(ray_angle) * 100,
                                  vars->player->y + sin(ray_angle) * 100, 0x00ff0000);
        ray_angle += fov_angle / num_ray;
        i++;
    }
    if (vars->rays != NULL)
        free(vars->rays);
    vars->rays = rays;
}

void ft_raycast_render(t_vars *vars, t_data *img)
{
    int i;
    t_point central;

    i = 0;
    central = ft_create_point(vars->player->x, vars->player->y, 0x00ff0000);
    while (i < (vars->win_width / WALL_STRIP_WIDTH))
    {
        ft_line_dda(img, central, vars->rays[i]);
        i++;
    }
}

void ft_raycast(t_vars *vars, t_data *img)
{
    ft_create_rays(vars);
    ft_raycast_render(vars, img);
}

我想我展示了帮助我调试此代码的所有代码。无论如何,我会让链接指向github仓库:

https://github.com/wblech/cub3d

P.S。我认为问题可能在于终点位置错误,并且线段移至其他位置。但是我不知道这是不是,如果不知道我该如何解决。

c math graphics raycasting
1个回答
0
投票

存在空格是因为您的视图确实有孔...

[您知道如果在某个n角度上投射FOV数组,那么在圆弧周长上所有距离上都只有n点,因此看起来越远,孔越大。如果要避免这种情况,请限制您的观察距离...并根据周长弧长计算射线数。

所以让我们举个例子:

l=128是视距(或地图大小),以[像素]为单位FOV=60*deg=1.0471975511965977461542144610932 rad是视场n=?是FOV中没有孔的最小射线数量

n >= FOV*l
n >= 134.04128655316451150773945101993
n = 135

如果您需要一些启发,请看一下:

© www.soinside.com 2019 - 2024. All rights reserved.