Я сделал raycaster на основе моих собственных математических знаний, все кажется хорошим, однако на некоторых ракурсах он показывает частичную стену рядом с реальной стеной.
Судя по моим исследованиям, кажется, быть проблемой, основанной на floor/ceil
, но ее исправление путем установки floor
везде приводит к этой проблеме
Я нахожусь на 3-м дне решения проблемы, и отсюда я теряю надежду. ..
Вот мой код:
Расчет луча
int worldMap[24][24]=
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1},
{1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1},
{1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1},
{1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1},
{1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1},
{1,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
t_ray ray_fst_quarter(t_ray r, t_conf conf)
{
while (worldMap[r.mpos.y][r.mpos.x] == 0)
{
r.opos.x = r.cpos.x;
r.opos.y = r.cpos.y;
r.cpos.x = floor(r.opos.x) + 1;
r.cpos.y = (r.cpos.x - r.opos.x) * r.coef.x + r.opos.y;
if (floor(r.cpos.y) > floor(r.opos.y))
{
r.cpos.y = floor(r.opos.y) + 1;
r.cpos.x = ((r.cpos.y - r.opos.y) / r.coef.x) + r.opos.x;
}
r.mpos.x = floor(r.cpos.x);
r.mpos.y = floor(r.cpos.y);
}
return (r);
}
t_ray ray_scd_quarter(t_ray r, t_conf conf)
{
while (worldMap[r.mpos.y][r.mpos.x] == 0)
{
r.opos.x = r.cpos.x;
r.opos.y = r.cpos.y;
r.cpos.x = ceil(r.opos.x) - 1;
r.cpos.y = (r.opos.x - r.cpos.x) * (-r.coef.x) + r.opos.y;
if (floor(r.cpos.y) > floor(r.opos.y))
{
r.cpos.y = floor(r.opos.y) + 1;
r.cpos.x = ((r.cpos.y - r.opos.y) / r.coef.x) + r.opos.x;
}
r.mpos.x = ceil(r.cpos.x);
r.mpos.y = floor(r.cpos.y);
}
return (r);
}
t_ray ray_trd_quarter(t_ray r, t_conf conf)
{
while (worldMap[r.mpos.y][r.mpos.x] == 0)
{
r.opos.x = r.cpos.x;
r.opos.y = r.cpos.y;
r.cpos.x = ceil(r.opos.x) - 1;
r.cpos.y = (r.opos.x - r.cpos.x) * -(r.coef.x) + r.opos.y;
if (ceil(r.cpos.y) < ceil(r.opos.y))
{
r.cpos.y = ceil(r.opos.y - 1);
r.cpos.x = -((r.opos.y - r.cpos.y) / r.coef.x) + r.opos.x;
}
r.mpos.x = ceil(r.cpos.x);
r.mpos.y = ceil(r.cpos.y);
}
return (r);
}
t_ray ray_frt_quarter(t_ray r, t_conf conf)
{
while (worldMap[r.mpos.y][r.mpos.x] == 0)
{
r.opos.x = r.cpos.x;
r.opos.y = r.cpos.y;
r.cpos.x = floor(r.opos.x) + 1;
r.cpos.y = (r.cpos.x - r.opos.x) * r.coef.x + r.cpos.y;
if (ceil(r.cpos.y) < ceil(r.opos.y))
{
r.cpos.y = ceil(r.opos.y) - 1;
r.cpos.x = -((r.opos.y - r.cpos.y) / r.coef.x) + r.opos.x;
}
r.mpos.x = floor(r.cpos.x);
r.mpos.y = ceil(r.cpos.y);
}
return (r);
}
Сортировка за какой квартал
static t_ray send_ray(t_ray r, double r_angle, t_win cub)
{
if ((r_angle / 100 > 269.999995 && r_angle / 100 <= 270.0000005)
|| (r_angle / 100 > 179.999995 && r_angle / 100 <= 180.0000005)
|| (r_angle / 100 > 89.999995 && r_angle / 100 <= 90.0000005)
|| (r_angle / 100 > 359.999995 && r_angle / 100 <= 360.0000005)
|| (r_angle / 100 > -1.0000005 && r_angle / 100 <= 0.0000005))
r_angle -= 0.04*100;
r.dir.x = cos((r_angle / 100) * M_PI / 180) + r.cpos.x;
r.dir.y = sin((r_angle / 100) * M_PI / 180) + r.cpos.y;
r.coef.x = (r.dir.y - r.cpos.y) / (r.dir.x - r.cpos.x);
r.mpos.x = floor(r.cpos.x);
r.mpos.y = floor(r.cpos.y);
if ((r_angle > 0 && r_angle <= 90*100) || r_angle >= 360*100)
r = ray_fst_quarter(r, *cub.conf);
else if (r_angle > 90*100 && r_angle <= 180*100)
r = ray_scd_quarter(r, *cub.conf);
else if (r_angle > 180*100 && r_angle <= 270*100)
r = ray_trd_quarter(r, *cub.conf);
else
r = ray_frt_quarter(r, *cub.conf);
return(r);
}