2014-09-03 52 views
2

我正在编程一个光线投射引擎。光线投射算法中的精确问题

射线的起点位置由谁是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值的方向。这是否会导致不准确?我需要区分更多角度吗?

回答

1

三角函数与弧度,不度工作。所以

tan(180 - current_angle) 

应该像

tan(Math.Pi - current_angle) 

注意,它等于

- tan(current_angle) 

如果您current_angle是在度是:

current_angle_radians = current_angle_degrees * Math.Pi/180 
+0

是的,我做我自己的棕褐函数转换弧度度。为了更好的可读性,我只是发布了tan()。 – 2014-09-03 12:54:33

1

我觉得你不准确上升时从削减1开始。

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

(旁白:(int) y/w将全面迈向零,因此将只适用于非负数的工作,您可能会考虑使用floor(x/w)。)