我正在尝试使用播放器(实心圆)创建2d地图,并且我开始创建光线投射。在进行光线投射之前,我试图绘制一个简单的FOV(视场),它应该是带有实心红色的弧形圆角,如下所示:
(图像仅是给出了实心红色实心圆弧的概念)
为了计算图形的弧线,我得到了弧线的第一个位置:
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));
}
}
但是问题是我不断得到带有一些点和空格的图像:
(大小可以。问题是空白和点)
请在下面找到与我要执行的弧(伪射线投射)相关的代码:
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。我认为问题可能在于终点位置错误,并且线段移至其他位置。但是我不知道这是不是,如果不知道我该如何解决。
存在空格是因为您的视图确实有孔...
[您知道如果在某个n
角度上投射FOV
数组,那么在圆弧周长上所有距离上都只有n
点,因此看起来越远,孔越大。如果要避免这种情况,请限制您的观察距离...并根据周长弧长计算射线数。
所以让我们举个例子:
l=128
是视距(或地图大小),以[像素]为单位FOV=60*deg=1.0471975511965977461542144610932 rad
是视场n=?
是FOV中没有孔的最小射线数量
n >= FOV*l
n >= 134.04128655316451150773945101993
n = 135
如果您需要一些启发,请看一下: