4

I am trying to write a raycasting algorithm described in this article. I use a coordinate system where y increases upward, x increases to the left. The variable names in the following code snippet are taken from the article, I will describe them so that the code is easier to read:

rayDirX and rayDirY are coordinates of the vector pointing from the player's position on the map in the direction where the ray is being cast, alpha is the angle between this ray and the origin.

Px, Py are precise coordinates of the player's position on the map

Ax, Ay are the precise coordinates of the first horizontal intersection, later other horizontal intersections.

Bx, By are the precise coordinates of the first vertical intersection, later other vertical intersections.

horXa, horYa, vertXa, vertYb are the step increments, which are constant after finding the first intersection. I suspect that the problem with the algorithm is that these values are not calculated correctly.

mapX, mapY are the coordinates of the lower left corner of an intersection on a map. This is used to check if there is a wall on this position in the array map[][].

Horizontal and vertical intersections are checked alternately. Ax, Ay, or Bx, By should hold the precise position of the intersection.

// Calculate the initial intersections
// Horizontal intersections
// If the ray is facing up
if (rayDirY > 0)
{
    horYa = 1;
    Ay = mapY+1;
}
// If the ray is facing down
else
{
    horYa = -1;
    Ay = mapY;
}
horXa = Math.abs(horYa)/tanAlpha;
Ax = Px + (Ay-Py)/tanAlpha;
// Vertical intersections
// If the ray is facing right
if (rayDirX > 0)
{
    vertXa = 1;
    Bx = mapX+1;
}
// If the ray is facing left
else
{
    vertXa = -1;
    Bx = mapX;
}
vertYa = Math.abs(vertXa)*tanAlpha;
By = Py + (Px-Bx)*tanAlpha;

//Loop to find where the ray hits a wall
//Number of texture to display
int texNum;
boolean horizontal = Math.abs(Ax * Math.cos(alpha)) < Math.abs(Bx*Math.cos(alpha));
//This loop runs for each ray with the setup above
while(true) {
    // Check horizontal intersection
    if (horizontal)
    {
        mapX = (int)Math.floor(Math.abs(Ax));
        mapY = (int)Math.floor(Math.abs(Ay));
        if(mapX > mapWidth-1) mapX = mapWidth-1;
        if(mapY > mapHeight-1) mapY = mapHeight-1;
        if(mapX < 0) mapX = 0;
        if(mapY < 0) mapY = 0;
        texNum = map[mapX][mapY];
        if(texNum > 0) break;
        Ax += horXa;
        Ay += horYa;
        horizontal = false;
    }
    else {
        mapX = (int)Math.floor(Math.abs(Bx));
        mapY = (int)Math.floor(Math.abs(By));
        if(mapX > mapWidth-1) mapX = mapWidth-1;
        if(mapY > mapHeight-1) mapY = mapHeight-1;
        if(mapX < 0) mapX = 0;
        if(mapY < 0) mapY = 0;
        texNum = map[mapX][mapY];
        if (texNum > 0) break;
        Bx += vertXa;
        By += vertYa;
        horizontal = true;
    }
}

Using this algorithm, the image is not rendered properly, see the screenshot. I suspect that it is because of horYa, Ay, vertXa, Bx not being calculated correctly. UPDATE: After some debugging efforts, it seems that sometimes we choose to compute horizontal intersection instead of vertical and vice versa... Really strange!

enter image description here

Can you please spot an error in the algorithm? Thank you for any input!

mirgee
  • 390
  • 2
  • 13
  • You could debug you implementation with known grid and ray. I've used another method http://stackoverflow.com/questions/24679963/precise-subpixel-line-drawing-algorithm-rasterization-algorithm/24680894#24680894 – MBo Apr 24 '16 at 12:43
  • @MBo I have a known grid and ray, but I can't figure out what is wrong from the rasterized image. It's just a mess like on the screenshot above... – mirgee Apr 24 '16 at 12:54

0 Answers0