You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Python Raycaster(光线投射器)中的鱼眼效应?

修复Python光线投射器中的鱼眼效应问题

我始终无法修复Python光线投射器(Raycaster)中的鱼眼效应,代码可正常运行,但查阅相关方案后仍怀疑存在更深层问题。代表“墙体”的竖线本该笔直却呈现弯曲,推测原因是玩家发出的射线与直墙交互时长度存在差异。我是Python新手,曾尝试将原始射线长度乘以玩家方向与射线方向差值的余弦值,但未见效果。

相关代码如下:

#  imports
import turtle, math

#  variables 

raycastAngle = 90
raycastRayNum = 100
raycastRayRange = 100
raycastRayStep = 2

screenX, screenY = 800, 600
screen = turtle.Screen()
screen.screensize(screenX, screenY)
screen.tracer(0)
screen.bgcolor(0, 0, 0)

raycaster = turtle.Turtle()
raycaster.penup()
raycaster.hideturtle()

player = turtle.Turtle()
player.penup()
player.setheading(45)
player.hideturtle()

sceneStamp = turtle.Turtle()
sceneStamp.penup()
sceneStamp.hideturtle()

walls = {

    'test wall1':{

        'x': 70,
        'y': 70,
        'width': 100,
        'height': 100
    },

}

#  subprograms

def distFromCoords(startCoord, endCoord):
    xDist = endCoord[0] - startCoord[0]
    yDist = endCoord[1] - startCoord[1]
    
    distance = math.sqrt((xDist * xDist) + (yDist * yDist))
    roundedDistance = round(distance)
    return roundedDistance
    
def isInsideWall(turtle):
    turtleX, turtleY = turtle.xcor(), turtle.ycor()
    
    for wall in walls.values():
        wallX, wallY = wall['x'], wall['y']
        wallWidth, wallHeight = wall['width'], wall['height']

        left = wallX - wallWidth / 2
        right = wallX + wallWidth / 2
        bottom = wallY - wallHeight / 2
        top = wallY + wallHeight / 2

        if left <= turtleX <= right and bottom <= turtleY <= top:
            return True

    return False

def raycast(angle, rayNum, rayRange, rayStep, showRay):
    raycaster.clear()
    startAngle = player.heading() - (angle / 2)

    rayLengths = []

    for i in range(rayNum):
        raycaster.penup()
        raycaster.goto(player.xcor(), player.ycor())
        raycaster.setheading(startAngle + (i * (angle / rayNum)))
        
        if showRay:
            raycaster.pendown()

        for j in range(rayRange // rayStep):
            raycaster.forward(rayStep)
            if isInsideWall(raycaster):
                break
        
        rayLengths.append(distFromCoords([player.xcor(), player.ycor()], [raycaster.xcor(), raycaster.ycor()]))
    
    return rayLengths
    
def drawScreen(rayLengths):
    global screenX, screenY
    global raycastAngle, raycastRayNum, raycastRayRange, raycastRayStep

    sceneStamp.clear()
    sceneStamp.penup()
    sceneStamp.pensize(3)
    sceneStamp.goto(-(screenX // 2), 0)

    for i in range(len(rayLengths)):
        rayLength = rayLengths[i]

        height = screenY * (1 - (rayLength / raycastRayRange))
        height = max(0, min(screenY, height))
        sceneStamp.color(0, 0, (0 + (height / screenY)))

        sceneStamp.sety(height / 2)
        sceneStamp.pendown()
        sceneStamp.sety(-height / 2)
        sceneStamp.penup()

        sceneStamp.setx(sceneStamp.xcor() + (screenX / raycastRayNum))

def gameUpdate():
    screen.update()
    drawScreen(raycast(raycastAngle, raycastRayNum, raycastRayRange, raycastRayStep, True))
    turtle.ontimer(gameUpdate, 15)

#  main program 
gameUpdate()

screen.listen()
screen.mainloop()

效果截图:
鱼眼效应下的弯曲墙体

内容的提问来源于stack exchange,提问作者George Hyde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:20:08