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

Pythonista中Pillow新RGB窗口无法生成的技术求助

透视投影程序无法显示RGB窗口的问题

我之前写了一个透视投影测试程序,导入PIL.ImageDraw等模块后,用draw.line能正常绘制线条并显示RGB窗口。但在新程序里,添加了基于math库三角函数的xyz点矩阵构建代码和变量输入逻辑后,同样用draw.line,RGB窗口完全不显示,程序无报错也不终止,运行环境是iOS iPad Pro上的Pythonista。


可正常运行的透视投影代码

import PIL.ImageDraw as ImageDraw,PIL.Image as Image, PIL.ImageShow as ImageShow
im = Image.new("RGB", (1200,800))
draw = ImageDraw.Draw(im)

GL_z = 0
PP_y = 0
SP_x = 300

SP_y = -400

SP_z = 600

org=600

answer=0

width=100

depth=500

height=500

SP_z1=SP_z+height

px_1 = org

py_1 = org

px_2 = org+90

py_2 = 50 + org

px_3 = -160 + org

py_3 = 550 + org

px_4 = -250 + org

py_4 = 500+org

while answer==0:

SP_z1=SP_z-height

px1_1 = ((px_1 - SP_x)/(py_1 - SP_y))*(py_1 - PP_y)
px1_2 = ((px_2 - SP_x)/(py_2 - SP_y))*(py_2 - PP_y)
px1_3 = ((px_3 - SP_x)/(py_3 - SP_y))*(py_3 - PP_y)
px1_4 = ((px_4 - SP_x)/(py_4 - SP_y))*(py_4 - PP_y)

py1_1 = ((SP_z-GL_z)/(py_1-SP_y))*(py_1-PP_y)
py1_2 = ((SP_z-GL_z)/(py_2-SP_y))*(py_2-PP_y)
py1_3 = ((SP_z-GL_z)/(py_3-SP_y))*(py_3-PP_y)
py1_4 = ((SP_z-GL_z)/(py_4-SP_y))*(py_4-PP_y)

py1_5 = ((SP_z1-GL_z)/(py_1-SP_y))*(py_1-PP_y)
py1_6 = ((SP_z1-GL_z)/(py_2-SP_y))*(py_2-PP_y)
py1_7 = ((SP_z1-GL_z)/(py_3-SP_y))*(py_3-PP_y)
py1_8 = ((SP_z1-GL_z)/(py_4-SP_y))*(py_4-PP_y)

px1_1old = px1_1
px1_2old = px1_2 
px1_3old = px1_3
px1_4old = px1_4

py1_1old = py1_1
py1_2old = py1_2
py1_3old = py1_3
py1_4old = py1_4

py1_5old = py1_5
py1_6old = py1_6
py1_7old = py1_7
py1_8old = py1_8

SP_yold = SP_y



draw.line((0,SP_y,1200,SP_y),fill=(255,255,255))

draw.line((px1_1,py1_1,px1_2,py1_2),fill=(0,0,255))
draw.line((px1_2,py1_2,px1_3,py1_3),fill=(0,255,0))
draw.line((px1_3,py1_3,px1_4,py1_4),fill=(255,255,255))
draw.line((px1_4,py1_4,px1_1,py1_1),fill=(100,255,0))

draw.line((px1_1,py1_1,px1_1,py1_5),fill=(255,255,255))
draw.line((px1_1,py1_5,px1_2,py1_6),fill=(255,255,255))
draw.line((px1_2,py1_6,px1_3,py1_7),fill=(255,255,255))
draw.line((px1_3,py1_7,px1_4,py1_8),fill=(255,255,255))
draw.line((px1_4,py1_8,px1_4,py1_4),fill=(150,150,0))



#draw.line((px1_1,py1_1,px1_2,py1_2),fill=(255,255,255))
#draw.line((px1_2,py1_2,px1_3,py1_3),fill=(255,255,255))
#draw.line((px1_3,py1_3,px1_4,py1_4),fill=(255,255,255))
#draw.line((px1_4,py1_4,px1_1,py1_1),fill=(255,255,255))

im.show()

move = input("''")

if move == "w":
    SP_y += 50
if move == "s":
    SP_x -= 50
if move == "z":
    SP_y -= 50
if move == "a":
    SP_x += 50  
if move == "-":
    SP_z -= 50      
if move == "=":
    SP_z += 50          
    
    
draw.line((0,SP_yold,1200,SP_yold),fill=(0,0,0))    
    
draw.line((px1_1old,py1_1old,px1_2old,py1_2old),fill=(0,0,0))
draw.line((px1_2old,py1_2old,px1_3old,py1_3old),fill=(0,0,0))
draw.line((px1_3old,py1_3old,px1_4old,px1_4old),fill=(0,0,0))
draw.line((px1_4old,py1_4old,px1_1old,py1_1old),fill=(0,0,0))

draw.line((px1_1old,py1_1old,px1_1old,py1_5old),fill=(0,0,0))
draw.line((px1_1old,py1_5old,px1_2old,py1_6old),fill=(0,0,0))
draw.line((px1_2old,py1_6old,px1_3old,py1_7old),fill=(0,0,0))
draw.line((px1_3old,py1_7old,px1_4old,py1_8old),fill=(0,0,0))
draw.line((px1_4old,py1_8old,px1_4old,py1_4old),fill=(0,0,0))

无法正常显示的新程序代码

import math

import decimal 
decimal.getcontext().prec = 6

import PIL.ImageDraw as ImageDraw,PIL.Image as Image, PIL.ImageShow as ImageShow 
 im = Image.new("RGB", (1200,800))
draw = ImageDraw.Draw(im)

PP_y = 0
SP_x = 300
SP_y = -400
SP_z = 600
org=600
answer=0


dims=[]
for i in range (1, 5):
    dim = int(input())
    dims.append(dim)

dims[3] = (dims[3]*math.pi)/180


obj1 = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18],[19,20,21],[22,23,24]]

y1 = [0,0,0,0,0,0,0,0]
y2 = [0,0,0,0,0,0,0,0]
y3 = [0,0,0,0,0,0,0,0]
x1 = [0,0,0,0,0,0,0,0]
z1 = [0,0,0,0,0,0,0,0]
ymod = [0,0,0,0,0,0,0,0]
xmod = [0,0,0,0,0,0,0,0]

obj1[0]=[0,0,0]

obj1[1]=[dims[0] * math.cos(dims[3]),dims[0] * math.sin(dims[3]),0]

obj1[2]=[obj1[1][0] - (dims[1] * math.sin(dims[3])),obj1[1][1] + (dims[1] * math.cos(dims[3])),0]

obj1[3]=[dims[1] * math.sin(dims[3]),dims[1] * math.cos(dims[3]),0]

obj1[4]=[0,0,dims[2]]

obj1[5]=[dims[0] * math.cos(dims[3]),dims[0] * math.sin(dims[3]),dims[2]]

obj1[6]=[obj1[1][0] - (dims[1] * math.sin(dims[3])),obj1[1][1] + (dims[1] * math.cos(dims[3])),dims[2]]

 obj1[7]=[dims[1] * math.sin(dims[3]),dims[1] * math.cos(dims[3]),dims[2]]

for i in range (0,7):
    y1[i]=obj1[i][1]-PP_y
    y2[i]=obj1[i][1]-SP_y
    y3[i]=y1[i]/y2[i]
    x1[i]=obj1[i][0]-SP_y
    z1[i]=obj1[i][2]-SP_z
    obj1[i][0]=obj1[i][0] - (x1[i] * y3[i])
    obj1[i][2]=obj1[i][2] - (z1[i] * y3[i])

#print(dims)
#print(obj1)
#print(y1,y2,y3,x1,z1,xmod,ymod)


while (True):

    draw.line((obj1[0][0],obj1[0][2],obj1[1][0],obj1[1][2]),fill=(255,255,255))

问题原因及解决步骤

1. 缺少图像显示调用

新程序仅在循环中执行draw.line绘制,但从未调用im.show()渲染窗口,这是窗口不显示的核心原因。旧程序每次循环都会调用im.show()更新显示。

2. 无限循环无退出逻辑

while (True)是无限循环,没有终止条件,程序会一直重复绘制但无法停止。需要添加类似旧程序的输入判断来退出循环。

3. 坐标未映射到画布范围

透视计算后的obj1坐标可能落在1200x800画布之外,导致线条不可见。可添加坐标偏移(如加上org=600),确保点处于可视区域:

# 透视计算后添加偏移
for i in range(0,8):
    obj1[i][0] += org
    obj1[i][2] += org

4. 代码缩进错误

新程序中im = Image.new(...)和obj1[7]=[...]前有多余空格,会触发语法错误,需修正缩进。

修正后的核心代码片段

# 修正缩进的图像初始化
import PIL.ImageDraw as ImageDraw,PIL.Image as Image, PIL.ImageShow as ImageShow 
im = Image.new("RGB", (1200,800))
draw = ImageDraw.Draw(im)

# ... 其他代码 ...

# 添加坐标偏移
for i in range(0,8):
    obj1[i][0] += org
    obj1[i][2] += org

while True:
    # 清空画布避免重叠
    draw.rectangle((0,0,1200,800), fill=(0,0,0))
    draw.line((obj1[0][0],obj1[0][2],obj1[1][0],obj1[1][2]),fill=(255,255,255))
    # 显示图像
    im.show()
    # 添加退出逻辑
    move = input("输入q退出,其他键刷新:")
    if move == "q":
        break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 05:50:11