Lua射线投射问题

我一直在为Ti Nspire CX(使用Lua)构建的射线投射引擎而日复一日地工作,但是在射线碰撞方面遇到了问题。

根据我对可能存在问题区域的摆弄,屏幕上射线的绘制没有问题:

a wall

在这方面,我还做了很多调试工作,例如显示从玩家向外发射的射线所在的坐标。我认为碰撞部分存在问题,因为当我打印每个射线的半径时,它们都达到了我设置的最大距离40。这是碰撞和单射线管理代码:

function ray()
    radius = 1
    for n = 1, 40, 1 do -- 增加的testdot
        x_ray = x + (radius * math.cos(rayf * 3.141592653/180))
        y_ray = y - (radius * math.sin(rayf * 3.141592653/180))
        --print(math.floor(x_ray,3), math.floor(y_ray,3), rayf, radius)
        for i = 1, 4, 1 do --for k,v in pairs(map) do -- 测试testdot和墙壁的碰撞
            --print("X  ",v[1],"<-->",math.floor(x_ray),"<-->",v[3])
            --print("Y  ",v[2],"<-->",math.floor(y_ray),"<-->",v[4])'

            ------------------------------------
            if (
                math.min(map[i][1],map[i][3]) <= x_ray and x_ray <= math.max(map[i][1],map[i][3])
            ) and (
                math.min(map[i][2],map[i][4]) <= y_ray and y_ray <= math.max(map[i][2],map[i][4])
            ) then
                print("碰撞")
                --return true
            end
            ------------------------------------
        end
        radius = n
    end
end

我知道第二个循环可以缩短,但我在调试过程中做到了这一点,以找出为什么这样做不会有效地运行。

围绕------------------------------------的区域是射线不会碰撞/超过/丢失的地方...我不知道为什么这不起作用,有什么建议吗?

只是为了参考,这种碰撞基于我遇到问题的python程序在这里,当然是碰撞部分。

变量值:

x,y是玩家的位置(在进行射线投射时,它将保持静态)

radius是单个射线的当前半径,只要未检测到碰撞,就会继续增加

rayf是射线的当前度数(不是相对于玩家的度数)。在程序开始时由玩家度数(在这里没有显示但称为'facing')加30,然后顺时针旋转,直到满足60度的视野角度。

X-ray,y_ray是单个射线的当前点,并将向指定的rayf值继续增加,半径将增加为最后的for循环中的n。(必须注意,度数在典型的单位圆中相同,而不是镜像以匹配镜像y轴;即90度为向上,180度为向下。)

点赞
用户4687565
用户4687565

这不是代码审查网站,但我会尝试先用更容易理解的方式编写代码,然后在代码注释中猜测错误。

function ray(x,y,rayf,map)
  %你确定全局变量 x、y、rayf 没有被覆盖吗?
  %如果0度是“右”,“90度”是“上”,“180度”是“左”,那这些是正确的吗?
  local x_proj = math.cos(rayf* 3.141592653/180);
  local y_proj = -math.sin(rayf* 3.141592653/180);
  for radius=1,40 do
    local x_ray = x + radius * x_proj
    local y_ray = y + radius * y_proj
    for i=1,4 do
      %我理解 map[i] 是房间特定侧面上的一个特定矩形(例如,map [1] 位于屏幕左侧边缘)
      %这样对吗?
      local wall_left_edge = math.min ( map[i][1],map[i][3] )
      local wall_right_edge = math.max ( map[i][1],map[i][3] )
      %如果我理解正确,小的 y 值在大的 y 值上方
      local wall_top_edge = math.min ( map[i][2], map[i][4] )
      local wall_bottom_edge = math.max ( map[i][2], map[i][4] )
      %我不明白为什么不能事先对墙壁坐标进行排序
      %(例如,上-1、下-2、左-3、右-4if (wall_left_edge < x) and (x < wall_right_edge)
      and (wall_top_edge < y) and (y < wall_bottom_edge) then
        %这不是检测碰撞,
        %它检测光束是否进入矩形“map [i]”
        print("Collision")
      end
    end
  end
end

因此,考虑到最后一条评论,您定义的墙壁必须足够宽厚,以便光线能够步入其中:(wall_right_edge - wall_left_edge)>1 (1是半径循环的步骤)和 (wall_bottom_edge - wall_top_edge)>1。在角落墙壁必须重叠或者它们应该共享至少1的长度边界。

2018-03-27 23:00:06
用户9044814
用户9044814

原文:

The reason the rays were always going past 40 was because the for-loop wasnt being canceled, which is a great reason to include a return to break out of the function and continue the code (I thought a return was included, however it wasn't functioning correctly, as you see in the:

--return true

Past this, the raycasting worked fine, but not math.floor-ing the new ray coord's also made the ray shoot beyond 40, for some unknown reason.

翻译:

激光一直超过40的原因是因为for循环没有被取消,这是一个很好的理由来加入_return_来跳出函数并继续代码(我以为return已经包含在内了,但它没有正确地运行,如下所示:

--return true

除此之外,射线投射正常工作,但没有对新的射线坐标进行math.floor的运算也使射线超出了40,原因未知。

2018-03-30 15:24:36