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

Python Turtle体素引擎无绘图输出问题排查求助

你的体素引擎无绘图输出的原因及修复方案

核心问题分析

1. 全局变量未被正确修改

你的trig_vals()、set_point()等函数里,直接赋值sinx = m.sin(rotx)、xcord = x时,创建的是局部变量,并未修改全局作用域的变量。导致后续坐标计算始终使用初始的0或1值,完全失效。

解决:在函数内部用global关键字声明要修改的全局变量,比如:

def trig_vals():
    global sinx, cosx, siny, cosy
    sinx = m.sin(m.radians(rotx))
    cosx = m.cos(m.radians(rotx))
    siny = m.sin(m.radians(roty))
    cosy = m.cos(m.radians(roty))

2. 三角函数参数未转弧度

math.sin()/math.cos()仅接收弧度值,但你代码里的rotx=90、roty=-180是角度,直接传入会得到错误的三角函数值,旋转计算完全错误。

解决:用math.radians()把角度转成弧度,如上例所示。

3. 无限循环重复初始化屏幕

while True里每次调用setup(),会反复创建新的turtle屏幕,覆盖之前的状态;同时没有给turtle的事件循环留运行空间,窗口无法正常刷新。

解决:把setup()移到循环外仅执行一次,用t.mainloop()替代无限循环,或在循环中加入t.update()和延迟。

4. 绘图逻辑无效

  • Draw_Point()里pendown()后立刻penup(),没有任何实质绘图动作;
  • 距离计算dist = (m.sqrt((zcord * zcord) + (zcord * zcord)) / 15)逻辑错误,未正确计算点到相机的距离;
  • 屏幕坐标转换公式有误,且未处理zcord为0的情况(会触发除零错误)。

解决:调整绘图逻辑,确保pendown后有绘图动作(比如t.dot()),修正距离与坐标计算逻辑。

修正后的完整代码

import turtle as t
import math as m

# Voxel positions
xcord = 1
ycord = 1
zcord = -50

# Player position
camx = 0
camy = 0
camz = 0

# Player Rotation (角度)
rotx = 90
roty = -180

# Trig Values
sinx = 0
cosx = 0
siny = 0
cosy = 0

# Field of View
FOV = 60

# Distance and Pen Size
quality = 2


def trig_vals():
    global sinx, cosx, siny, cosy
    # 角度转弧度
    sinx = m.sin(m.radians(rotx))
    cosx = m.cos(m.radians(rotx))
    siny = m.sin(m.radians(roty))
    cosy = m.cos(m.radians(roty))


def set_point(x, y, z):
    global xcord, ycord, zcord
    xcord = x
    ycord = y
    zcord = z


def onscreen_point(x, y):
    global xcord, ycord
    xcord = x
    ycord = y


def calc_rotation(x, y, z):
    # 转换到相机坐标系
    set_point(x - camx, y - camy, z - camz)
    # Y轴旋转
    new_x = zcord * siny + xcord * cosy
    new_z = zcord * cosy - xcord * siny
    set_point(new_x, ycord, new_z)
    # X轴旋转
    new_y = zcord * cosx - ycord * sinx
    new_z = zcord * sinx + ycord * cosx
    set_point(xcord, new_y, new_z)


def Draw_Point(x, y, z, c):
    global xcord, ycord, zcord
    calc_rotation(x, y, z)
    
    # 避免除零错误,只处理相机前方的点
    if zcord <= 0:
        return
    
    # 透视投影转换
    scale = (200 - FOV) / zcord
    screen_x = xcord * scale
    screen_y = ycord * scale
    onscreen_point(screen_x, screen_y)
    
    # 检查是否在屏幕范围内
    if abs(screen_x) > 240 or abs(screen_y) > 180:
        return
    
    # 计算点到相机的距离,调整画笔大小
    dist = m.sqrt(xcord**2 + ycord**2 + zcord**2) / 15
    if dist > 99:
        return
    
    t.pencolor(c)
    t.pensize(max(1, quality * (100 - dist) / 50))  # 根据距离调整点大小
    t.penup()
    t.goto(screen_x, screen_y)
    t.pendown()
    t.dot()  # 绘制可见的点
    t.penup()


def setup():
    t.hideturtle()
    t.tracer(0, 0)  # 关闭自动刷新,提升性能
    screen = t.Screen()
    screen.setup(480, 360)
    screen.bgcolor("black")
    trig_vals()


# 初始化与测试
setup()
Draw_Point(1, 50, 50, "white")
t.update()  # 手动刷新屏幕
t.mainloop()  # 启动事件循环

额外说明

  • 关闭t.tracer()并手动调用t.update(),能大幅提升批量绘制体素时的性能;
  • 增加zcord <=0的判断,避免点在相机后方或重合导致的除零错误;
  • 用t.dot()替代无效的pendown/penup组合,确保能绘制出可见的点;
  • 调整画笔大小计算逻辑,让远处的点更小,符合透视效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:30:25