我无法使用此代码。它应该从输入函数生成分形图像。它将完美运行,然后打印出单色帆布而不是分形。当我将分形函数从Mandelbrot切换到Newton-Raphson时出现问题。与Mandelbrot不同,Newton-Raphson需要为要调用的函数单独定义。这就是给我带来麻烦的一点。我输入了一个print语句,它似乎正在运行,但它运行不正常。它运行所有点到最大迭代(MaxIt),然后给我一个彩色画布,认为它们都逃到无限。以下是当前代码的副本:
from tkinter import *
from math import *
#Creates widgets for user input
class Imagespecs(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.grid()
self.y_axis()
self.x_axis()
#Y axis input
def y_axis(self):
self.instruction = Label(self,text = "How many pixels high do you want the image?")
self.instruction.grid(row = 8, column = 0, columnspan = 2, sticky = N)
self.height = Entry(self)
self.height.grid(row = 10, column = 1, sticky = E)
#Enters info to run fractal generation
self.submit_button = Button(self,text = "Submit", command = self.fractals)
self.submit_button.grid(row = 14, column = 2, sticky = E)
#X axis input
def x_axis(self):
self.instruction2 = Label(self,text = "How many pixels wide do you want the image?")
self.instruction2.grid(row = 4, column = 0, columnspan = 2, sticky = E)
self.width = Entry(self)
self.width.grid(row = 6, column = 1, sticky = E)
#generates fractal
def fractals(self):
maxIt = 2
ds = 0.2e-1
eps = 5e-5
#Replace non-input
content = self.width.get()
content2 = self.height.get()
if content == "":
content = 500
if content2 == "":
content2 = 500
def f(z):
return z**3 + 5
print ('lalala')
#Create window specs
WIDTH = int(content2); HEIGHT = int(content)
xa = -1.0; xb = 1.0
ya = -1.0; yb = 1.0
maxIt = 300
window = Toplevel()
canvas = Canvas(window, width = WIDTH, height = HEIGHT, bg = "#000000")
img = PhotoImage(width = WIDTH, height = HEIGHT)
canvas.create_image((0, 0), image = img, state = "normal", anchor = NW)
#The Newton-Raphson iteration
h = HEIGHT
for y in range(HEIGHT):
print (h)
h = h - 1
zy = y * (yb - ya) / (HEIGHT - 1) + ya
for x in range(WIDTH):
zx = x * (xb - xa) / (WIDTH - 1) + xa
z = complex(zx, zy)
for i in range(maxIt):
dz = (f(z + complex(ds, ds)) - f(z)) / complex(ds, ds)
z0 = z - f(z) / dz
if abs(z0 - z) < eps:
break
rd = hex(i % 4 * 64)[2:].zfill(2)
gr = hex(i % 8 * 32)[2:].zfill(2)
bl = hex(i % 16 * 16)[2:].zfill(2)
img.put("#" + rd + gr + bl, (x, y))
#Run GUI
canvas.pack()
mainloop()
#Run the class and everything else
root = Tk()
root.title("Fractal GUI")
root.geometry("300x200")
app = Imagespecs(root)
root.mainloop()
答案 0 :(得分:0)
虽然您的代码中存在错误,例如缺少z = z0
行,这里的主要罪魁祸首是tkinter的PhotoImage的一个已知功能,它与不保存对图像和垃圾收集的引用有关:
Why do my Tkinter images not appear?
我已经重新编写代码以生成分形并尝试解决我注意到的那些问题:
from tkinter import *
MAX_ITERATIONS = 300
DS = 0.2e-1
EPS = 5e-5
# Create window specs
XA, XB = -1.0, 1.0
YA, YB = -1.0, 1.0
# Creates widgets for user input
class Imagespecs(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.y_axis()
self.x_axis()
self.image = None
# Y axis input
def y_axis(self):
instruction = Label(self, text="How many pixels high do you want the image?")
instruction.grid(row=8, column=0, columnspan=2, sticky=N)
self.height = Entry(self)
self.height.grid(row=10, column=1, sticky=E)
# Enters info to run fractal generation
submit_button = Button(self, text="Submit", command=self.fractals)
submit_button.grid(row=14, column=2, sticky=E)
# X axis input
def x_axis(self):
instruction = Label(self, text="How many pixels wide do you want the image?")
instruction.grid(row=4, column=0, columnspan=2, sticky=E)
self.width = Entry(self)
self.width.grid(row=6, column=1, sticky=E)
# generates fractal
def fractals(self):
def f(z):
return z**3 + 5
# Replace non-input
try:
width = int(self.width.get())
except ValueError:
width = 500
try:
height = int(self.height.get())
except ValueError:
height = 500
canvas = Canvas(Toplevel(), width=width, height=height, bg="#000000")
img = PhotoImage(width=width, height=height)
canvas.create_image((0, 0), image=img, state="normal", anchor=NW)
# The Newton-Raphson iteration
for y in range(height):
zy = y * (YB - YA) / (height - 1) + YA
for x in range(width):
zx = x * (XB - XA) / (width - 1) + XA
z = complex(zx, zy)
i = 0 # avoid undefined variable after loop
for i in range(MAX_ITERATIONS):
dz = (f(z + complex(DS, DS)) - f(z)) / complex(DS, DS)
z0 = z - f(z) / dz
if abs(z0 - z) < EPS:
break
z = z0
red = i % 4 * 64
green = i % 8 * 32
blue = i % 16 * 16
img.put("#%02x%02x%02x" % (red, green, blue), (x, y))
# Run GUI
canvas.pack()
self.image = img # save reference so image isn't GC'd!
# Run the class and everything else
root = Tk()
root.title("Fractal GUI")
root.geometry("400x150")
app = Imagespecs(root)
root.mainloop()