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
相关产品推荐
相关产品推荐

