lua - Lua - 如何补偿奇怪的 2D raycaster 引擎翘曲效果(不是鱼眼效果)
问题描述
基本上我在lua中写了一些代码:
function love.keypressed( key )
if key == "f11" then
fullscreen = not fullscreen
end
end
pPosX,pPosY = 1,8
pRot,pFOV,pViewRange = -90,95,15
lines = {{0,0,10,0},{10,0,10,10},{0,10,3,10},{7,10,10,10},{3,10,5,8},{5,8,7,10},{0,10,0,0},{2,2,2,8},{8,2,6,4},{2,5,4,5},{6,4,8,4}}
function love.conf(t)
t.console = true
end
function love.load()
fullscreen = true
love.window.setTitle("Raycaster")
love.window.setMode(1280,720,{})
love.window.setFullscreen(true, "desktop")
ScreenX,ScreenY = love.graphics.getDimensions()
end
function love.update(dt)
love.window.setFullscreen(fullscreen, "desktop")
if love.keyboard.isDown("w") then
pPosX,pPosY = math.cos(math.rad(pRot))*dt*3+pPosX,math.sin(math.rad(pRot))*dt*3+pPosY
end
if love.keyboard.isDown("s") then
pPosX,pPosY = math.cos(math.rad(pRot))*dt*-3+pPosX,math.sin(math.rad(pRot))*dt*-3+pPosY
end
if love.keyboard.isDown("left") then
pRot = pRot - dt*250
end
if love.keyboard.isDown("right") then
pRot = pRot + dt*250
end
if love.keyboard.isDown("a") then
pPosX,pPosY = math.cos(math.rad(pRot-90))*dt*3+pPosX,math.sin(math.rad(pRot-90))*dt*3+pPosY
end
if love.keyboard.isDown("d") then
pPosX,pPosY = math.cos(math.rad(pRot+90))*dt*3+pPosX,math.sin(math.rad(pRot+90))*dt*3+pPosY
end
fps = 1/dt
end
function love.draw()
love.graphics.setColor(0.5, 0.55, 1)
love.graphics.rectangle("fill",0,0,ScreenX,ScreenY/2)
love.graphics.setColor(0.35, 0.3, 0.3)
love.graphics.rectangle("fill",0,ScreenY/2,ScreenX,ScreenY/2)
ScreenX,ScreenY = love.graphics.getDimensions()
for i = 1,ScreenX,1 do
local scanX = pRot+(i-1)*pFOV/ScreenX-pFOV/2
local lx1,ly1 = math.cos(math.rad(scanX))*pViewRange+pPosX,math.sin(math.rad(scanX))*pViewRange+pPosY
local closest = 999999
for lns = 1,#lines,1 do
local x1,y1,x2,y2,x3,y3,x4,y4 = pPosX,pPosY,lx1,ly1,lines[lns][1],lines[lns][2],lines[lns][3],lines[lns][4]
t,u = ((x1-x3)*(y3-y4)-(y1-y3)*(x3-x4))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4)),
((x1-x3)*(y1-y2)-(y1-y3)*(x1-x2))/((x1-x2)*(y3-y4)-(y1-y2)*(x3-x4))
if t >= 0 and t <= 1 and u >= 0 and u <= 1 then
x,y = x1+t*(x2-x1),y1+t*(y2-y1)
Dist = math.sqrt((x - pPosX) ^ 2 + (y - pPosY) ^ 2)*math.cos(math.rad(pRot)-math.rad(scanX))
else
Dist = 999999
end
if Dist < closest then
closest = Dist
mmX,mmY = x,y
end
end
love.graphics.setColor(1.2-closest/pViewRange, 1.2-closest/pViewRange, 0)
love.graphics.line(pPosX*ScreenX/50,pPosY*ScreenX/50,mmX*ScreenX/50,mmY*ScreenX/50)
if closest <= pViewRange then
love.graphics.setColor(1.2-closest/pViewRange, 1.2-closest/pViewRange, 1.2-closest/pViewRange)
love.graphics.rectangle("fill",i,(ScreenY-(ScreenY*(pViewRange-closest)/pViewRange))/2,1,ScreenY*(pViewRange-closest)/pViewRange)
end
end
love.graphics.setColor(1,0,0)
for lns = 1,#lines,1 do
love.graphics.line(lines[lns][1]*ScreenX/50,lines[lns][2]*ScreenX/50,lines[lns][3]*ScreenX/50,lines[lns][4]*ScreenX/50)
end
love.graphics.setColor(1,1,1)
love.graphics.print(math.floor(fps+0.5),0.975*ScreenX,0)
end
pPosX,PposY 是玩家坐标 pRot,pFov,pViewRange 是以度为单位的玩家旋转,以度为单位的视野和视野范围,lines = {} 包含分为线 {x1,y1,x2,y2 的地图},引擎检查屏幕的分辨率并启动一个 for i 循环,该循环在 -pFov/2 处启动 scanX 变量并将其增加 pFov/ScreenX 直到达到 pFov/2,线段相交方程是从 wikipedia 复制的,我已经通过将 Dist(从玩家到交叉点的距离)乘以玩家角度的余弦减去 scanX 来补偿鱼眼效应,但仍然存在非常强烈的翘曲效果: https ://i.stack.imgur.com/ ztUN0.png 正如你在小地图中看到的那样,玩家正在向下看一条笔直的走廊,但看起来前面好像在弯曲。
解决方案
推荐阅读
- python - 图像处理:将普通图片转换为具有内在矩阵的 FishEye 图像
- android - Android TV 上的文件提供程序问题
- php - 如何在视图中调用辅助类的函数 - Laravel 5.8?
- spring-boot - Thymeleaf Spring 验证不显示
- javascript - 过滤 JS 问题
- opengl - glColor3f 和 glColor3d 的区别
- vb.net - 使用带有集成用户的访问令牌在 Megento 2.1.10 上出现 401 错误
- php - php/xslt 想要一个源文件
- etl - Vertica:将表中的数据插入弹性表时将字符串解析为 JSON
- c# - JetBrains Rider - 像 getter/setter 一样生成 Java?