c - 如何制作一个完整弧线的视野?尝试创建射线弧
问题描述
我正在尝试使用玩家(实心圆圈)创建 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)
对于其他光线,我使用这些计算:
ray_angle += fov_angle / num_ray;
num_ray 只是窗口的宽度,在这种情况下考虑它是 (11 * 32)
有了这个功能。我计算每条光线并保存在一个数组中
t_point *rays
对于 struct 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
PS我认为问题可能是终点在错误的位置并且线路转到不同的位置。但我不知道是否是这样,如果是,我不知道如何解决。
解决方案
空间在那里,因为你的观点真的有洞......
你知道,如果你n
以某个角度投射阵列,FOV
那么在所有距离上你只会n
在弧周上得到点,所以你看起来越远,洞就越大。如果您想避免这种情况,请限制您的视距......并从周边弧长计算光线数量。
所以让我们举个例子:
l=128
是以 [像素]
FOV=60*deg=1.0471975511965977461542144610932 rad
为单位的视距(或地图大小)是以 [rad]
n=?
为单位的视场是 FOV 中没有孔的最小光线数
n >= FOV*l
n >= 134.04128655316451150773945101993
n = 135
如果您想要一些灵感,请查看:
推荐阅读
- java - 使用 Jackson 反序列化数组 JSON 时出错
- reactjs - react-redux 在 componentDidMount 上重新渲染
- android - Android 导航 popBackStack
- python - globals()['variable']=在 .py 文件中设置的值不会反映在其他 .py 文件中使用时的值更改
- sql - SQL Server 2000 上没有活动的事务
- javascript - 过滤键值对内数组中的特定值
- python - tkinter 循环遍历按键列表
- php - 如何在 PHP 中使用 foreach 循环 MYSQL 月份将月份添加到 +1 个月?
- mongodb - 查找 mongoDB 中是否不存在集合
- html - 如何在网格单元格中垂直居中元素?