光线投射算法中的精度问题

时间:2014-09-03 02:48:09

标签: c++ algorithm raycasting dda

我正在编写一个光线投射引擎。

射线的起始位置由站在2D网格内的玩家的位置给出。

将光线投射到一个方向时,我必须确定光线相交的网格。

(概念的深入描述在这里:http://www.permadi.com/tutorial/raycast/rayc7.html

有一个小的不准确性会导致一些麻烦。我认为问题是由网格步骤的错误计算引起的。

但是我缺乏修复这个问题的数学理解。

问题描述:

当光线向左移动时,网格交叉步长与向右移动时的步长略有不同。

(为什么我甚至关心这个?:当垂直和水平交叉点彼此靠近时,特别是在角落里,一些水平网格交叉点比垂直网格交叉点更远离玩家的问题由于我使用不同的纹理进行垂直交叉,因此水平墙的外观会被破坏,因为在墙的小部分使用垂直纹理,即使它是水平墙。)

这个问题是由我的算法中的缺陷引起的吗?这就是我计算第一个水平网格交叉点和网格步长的方法:

找到第一个网格交叉点:

if (current_angle > 180) {
    first_grid_horizontal_y = ((int)p.pos_y / Field::width) * Field::width + Field::width;
} else {
    first_grid_horizontal_y = ((int)p.pos_y / Field::width) * Field::width - 1;
}
first_grid_horizontal_x = p.pos_x + (p.pos_y - first_grid_horizontal_y) / tan( 180 - current_angle);

计算步长:

if (current_angle > 180) {
    grid_stepsize_horizontal_y = Field::width;
    grid_stepsize_horizontal_x = Field::width / tan(current_angle - 180);
} else {
    grid_stepsize_horizontal_y = -Field::width;
    grid_stepsize_horizontal_x = Field::width / tan(180 - current_angle);
}

正如你所看到的,我一直在使用" 180 - 当前角度"确定x值的方向。这会导致不准确吗?我是否必须在角度之间区分更多?

2 个答案:

答案 0 :(得分:1)

三角函数适用于弧度,而不是度。所以

tan(180 - current_angle)

应该看起来像

tan(Math.Pi - current_angle)

请注意,它等于

- tan(current_angle)

如果你的current_angle的度数为:

current_angle_radians = current_angle_degrees * Math.Pi / 180

答案 1 :(得分:1)

我认为你的不准确性来自于上升时减1。

这背后的想法可能是你想得到一个块的最后一个像素的索引,但这是不必要的:你在这里做浮点数学和下一个水平交叉点的y值应该代表网格单元格之间的界限。如果你向下,它代表一个细胞的最高坐标;如果你向上,它代表最低坐标。

(旁白:(int) y / w将向零舍入,因此仅适用于非负数。您可以考虑使用floor(x / w)。)

相关问题