Precision problems in raycasting algorithm

1.6k views Asked by At

I am programming a raycasting engine.

The starting position of a ray is given by the position of the player who is standing inside a 2D-grid.

When casting a ray into a direction, I have to determine the grids that the ray is intersecting.

(The in-depth description of the concept is here: http://www.permadi.com/tutorial/raycast/rayc7.html)

There is a small inaccuracy which causes some trouble. I believe that the problem is caused by an incorrect calculation of the grid steps.

However I lack the mathematical understanding to fix that problem.

Problem description:

When the ray is heading to the left, the grid intersection step size is slightly different than the step size when it's heading to the right.

(Why do I even care about this?: It's causing the problem that some horizontal grid intersections are further away from the player than vertical grid intersections when vertical and horizontal intersections are close to each other, specifically in corners. Since I am using different textures for vertical intersections, the look of horizontal walls are ruined, because a vertical texture is used on small parts of the wall, even though it's an horizontal wall.)

Is this problem caused by a flaw in my algorithm? This is how I calculate the first horizontal grid intersection and the grid stepsize:

Find first grid intersection:

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);

Calculate the step size:

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);
}

As you can see I am always using "180 - current angle" to determine the direction of the x-value. Does this cause the inaccurancy? Do I have to differentiate more between angles?

2

There are 2 answers

0
M Oehm On

I think your inaccuracy comes from subracting 1 when going upwards.

The idea behind this is probably that you want to get the index of the last pixel of a block, but that is inneccessary: You are doing floating-point math here and the y value of the next horizontal intersection should represent the line between the grid cells. If you go downward, it represents to uppermost coordinate of a cell; if you go upwards it represents the lowermost coordinate.

(Aside: (int) y / w will round towards zero and will thus only work for non-negative numbers. You might consider using floor(x / w).)

1
MBo On

Trigonometric functions work with radians, not degrees. So

tan(180 - current_angle)

should look like

tan(Math.Pi - current_angle)

Note that it is equal to

- tan(current_angle)

If your current_angle is in degrees that:

current_angle_radians = current_angle_degrees * Math.Pi / 180