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

基于Pygame的自制立方体渲染器屏幕边缘出现畸变的原因是什么

问题原因

你遇到的畸变和光线计算无关,是透视投影的深度轴选择和计算逻辑错误导致的:
你当前代码把X轴作为投影分母(深度轴),但相机移动逻辑修改的是Y、Z轴坐标,当立方体偏离屏幕中心时,深度值(X轴差值)没有对应变化,导致横向/纵向的缩放比例完全错误,就会出现明显的拉伸畸变。

修复方案

只需修改两个部分的代码即可解决:

  1. 替换投影坐标计算逻辑,采用行业通用的Z轴为深度轴的透视投影规则,适配Pygame的Y轴向下坐标系:
# 把main函数里原来的投影计算代码
for i, point in enumerate(cube):  # gets all coords of cube
    pX = point[0] - camCoord[0]
    pY = point[1] - camCoord[1]
    pZ = point[2] - camCoord[2]
    mpX = pZ / pX
    mpY = pY / -pX  # canvas Y deviation from origin
    newCoords = coordConvert(mpX * scale, mpY * scale)
    ...

# 替换为以下逻辑
for i, point in enumerate(cube):
    pX = point[0] - camCoord[0]
    pY = point[1] - camCoord[1]
    pZ = point[2] - camCoord[2]
    # 过滤相机后方的点,避免除零和反向投影
    if pZ <= 0:
        continue
    # 透视投影核心公式:投影坐标 = 世界坐标 * 焦距 / 深度
    mpX = (pX * scale) / pZ
    mpY = (-pY * scale) / pZ
    newCoords = coordConvert(mpX, mpY)
    cubeCoords[i][0] = newCoords[0]
    cubeCoords[i][1] = newCoords[1]
    drawCircle(newCoords[0], newCoords[1])
  1. 调整立方体初始位置和操控逻辑,符合用户直觉:
  • 把moveCubeCoords = [8, -4, -4]修改为moveCubeCoords = [0, 0, 10],让立方体初始位于相机正前方10单位处
  • 调整onEvent的按键映射,让方向键对应相机的上下左右平移:
def onEvent(event):
    if event.key == pygame.K_UP:
        camCoord[1] -= camSpeed
    if event.key == pygame.K_DOWN:
        camCoord[1] += camSpeed
    if event.key == pygame.K_RIGHT:
        camCoord[0] += camSpeed
    if event.key == pygame.K_LEFT:
        camCoord[0] -= camSpeed
    # 可选添加W/S键控制相机前后移动
    if event.key == pygame.K_w:
        camCoord[2] += camSpeed
    if event.key == pygame.K_s:
        camCoord[2] -= camSpeed
    print(camCoord)

修改完成后无论怎么移动相机,立方体都会保持正确的透视比例,不会出现异常畸变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 20:09:03