光线投射不准确地计算交叉点

时间:2016-04-24 12:04:34

标签: java algorithm graphics 3d raycasting

我正在尝试编写this文章中描述的光线投射算法。我使用坐标系,其中y向上增加,x增加到左边。以下代码片段中的变量名称取自文章,我将对其进行描述,以便代码更易于阅读:

rayDirXrayDirY是向量的坐标,指向玩家在地图上投射光线的方向上的位置,alpha是两者之间的角度这条光线和原点。

Px, Py是玩家在地图上的位置的精确坐标

Ax, Ay是第一个水平交叉点的精确坐标,后来是其他水平交叉点。

Bx, By是第一个垂直交叉点的精确坐标,后来是其他垂直交叉点。

horXa, horYa, vertXa, vertYb是步长增量,在找到第一个交点后不变。我怀疑算法的问题是这些值没有正确计算。

mapX, mapY是地图上十字路口左下角的坐标。这用于检查数组map[][]中此位置是否有墙。

交替检查水平和垂直交叉点。 Ax, AyBx, By应保持交叉点的精确位置。

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

使用此算法,图像无法正确渲染,请参见屏幕截图。我怀疑是因为horYa, Ay, vertXa, Bx无法正确计算。更新:经过一些调试工作后,似乎有时我们选择计算水平交叉而不是垂直交叉,反之亦然......真的很奇怪!

enter image description here

您能否在算法中发现错误?感谢您的任何意见!

0 个答案:

没有答案