我写了一个使用turtle来绘制Mandelbrot集的函数,但是对于任何像样的分辨率来说它都非常慢(约10分钟),我怎样才能使我的代码更高效?
import math, turtle
screen = turtle.Screen()
screen.setup(width=1000, height=600 ,startx=0, starty=0)
screen.bgcolor('black')
screen.tracer(0)
pen = turtle.Turtle()
pen.penup()
pen.speed(10)
width = 800
height = 600
MAX_ITER=80
def draw_mandelbrot(c):
z = 0
n = 0
while abs(z) <= 2 and n < MAX_ITER:
z = z * z + c
n += 1
return n
def generate_mandelbrot_set(StartR, StartI, EndR, EndI):
screen.setworldcoordinates(StartR, StartI, EndR, EndI)
screen.bgcolor("black")
for x in range(width):
for y in range(height):
c = complex(StartR + (x / width) * (EndR - StartR), StartI + (y / height) * (EndI - StartI))
m = draw_mandelbrot(c)
color = (255 - int(m * 255 / MAX_ITER)) / 255
pen.goto(StartR + (x / width) * (EndR - StartR), StartI + (y / height) * (EndI - StartI))
if y == 0:
pen.pendown()
elif y == height-1 :
pen.penup()
pen.color(color, color, color)
pen.dot()
generate_mandelbrot_set(-2,-1,1,1)
screen.update()
screen.mainloop()
我是编码新手,因此我们将不胜感激!
我用 80x60 分辨率尝试了你的代码,我真的很喜欢小乌龟线的外观。但在 800x600 的分辨率下,海龟是不适合这项工作的工具:不仅艺术线条不可见,Python 还会花费大量时间做一些可爱的事情,例如动画海龟运动(仅在速度快时禁用) 11)。
我的建议是放弃海龟并使用带有 canvas 对象的图形界面,您可以在其中放置单个像素。 Python 附带了 Tkinter,一个简单但高效的库可以做到这一点。
这是翻译为 Tkinter 的代码,在 7 秒内渲染:
from tkinter import Tk, Canvas, PhotoImage, mainloop
WIDTH = 800
HEIGHT = 600
MAX_ITER=80
def draw_mandelbrot(c):
z = 0
n = 0
while abs(z) <= 2 and n < MAX_ITER:
z = z * z + c
n += 1
return n
def generate_mandelbrot_set(StartR, StartI, EndR, EndI):
for x in range(WIDTH):
for y in range(HEIGHT):
c = complex(StartR + (x / WIDTH) * (EndR - StartR), StartI + (y / HEIGHT) * (EndI - StartI))
m = draw_mandelbrot(c)
color = (255 - int(m * 255 / MAX_ITER))
color_str = '#{0:02x}{0:02x}{0:02x}'.format(color)
img.put(color_str, (x, y))
window = Tk()
canvas = Canvas(window, width=WIDTH, height=HEIGHT, bg="#000000")
canvas.pack()
img = PhotoImage(width=WIDTH, height=HEIGHT)
generate_mandelbrot_set(-2,-1,1,1)
# Important: add the image pixels to canvas *after* drawing.
# Otherwise each added pixel will cause the canvas to re-render.
canvas.create_image((WIDTH/2, HEIGHT/2), image=img, state="normal")
mainloop()