Python 如何在Zelle graphics中加快分形渲染?

Python 如何在Zelle graphics中加快分形渲染?,python,python-3.x,fractals,zelle-graphics,Python,Python 3.x,Fractals,Zelle Graphics,只需100次迭代,渲染此mandelbrot集需要一个多小时,而10000次迭代则需要10个小时。有没有办法让它更快: from graphics import * width = 700 height = 700 win = GraphWin("Mandelbrot",width,height) spacing = 1 zoom = 0.1 xOffset = -0.171 yOffset = 0.61 win.setBackground('black') for x in range(0

只需100次迭代,渲染此mandelbrot集需要一个多小时,而10000次迭代则需要10个小时。有没有办法让它更快:

from graphics import *

width = 700
height = 700
win = GraphWin("Mandelbrot",width,height)
spacing = 1
zoom = 0.1
xOffset = -0.171

yOffset = 0.61
win.setBackground('black')
for x in range(0,width,spacing):
    for y in range(1,height,spacing):
        a = ((x / width) * zoom) - xOffset
        b = ((y / height) * zoom) - yOffset

        pt = Point(x,y)


        n = 0
        ca = a
        cb = b
        while(n<10000):
            aa = a * a - b * b
            bb = 2 * a * b
            a = aa + ca
            b = bb + cb
            n+=1
            if(abs(a+b) > 2000):
                break
            if(n < 2000):
               pt.setFill('black')
            if(n>5000):
                pt.setFill('grey')
            if(n>1000):
                pt.setFill('white')

        pt.draw(win)
从图形导入*
宽度=700
高度=700
win=图形宽度(“曼德尔布罗特”,宽度,高度)
间距=1
缩放=0.1
xOffset=-0.171
yOffset=0.61
胜利。挫折(“黑色”)
对于范围内的x(0,宽度,间距):
对于范围内的y(1,高度,间距):
a=((x/宽度)*缩放)-xOffset
b=((y/高度)*缩放)-y偏移
pt=点(x,y)
n=0
ca=a
cb=b
而(n 2000):
打破
如果(n<2000):
零件设置填充(“黑色”)
如果(n>5000):
零件设置填充(“灰色”)
如果(n>1000):
零件设置填充(“白色”)
抽签(赢)

最快的方法很可能是使用。 有关此方法的详细信息,请参阅

对于纯Python,使用本机加速循环。还可以使用该函数快速计算复数的大小:

>>> def mandle(c, boundary=2.0, maxloops=10000):
        # https://en.wikipedia.org/wiki/Mandelbrot_set
        z = 0.0j
        for i in range(maxloops):
            z = z * z + c
            if abs(z) > boundary:
                break
        return i

>>> mandle(0.04 + 0.65j)
21
>>> mandle(0.04 + 0.66j)
16
>>> mandle(0.04 + 0.67j)
12
渲染本身不太可能是程序的慢部分(10000个循环可以缩短绘制点的时间)。也就是说,如果要加快渲染速度,通常唯一的选择是每次调用图形库时绘制多个点


最后,考虑是否真的希望最大迭代次数为10000次。您最多可以通过200次迭代获得良好的结果。

除了@RaymondHettinger建议的复数之外,我们还可以在Zelle graphics方面做一些事情来加快速度。第一个是不要使用
Point()
,它有太多的开销。
win
实例本身有一个用于位图操作的
plot()
方法,该方法没有
Point()
的开销,即无法取消绘制,无法移动

第二个是关闭自动刷新,并对每一列进行我们自己的屏幕刷新。最后,简单地避免做任何不需要的计算——例如,
ca
可以在外部循环中计算,而不是在内部循环中计算。颜色可以在最里面的循环之外计算,等等

这是我的重做,如上所述——对70 x 70图像进行计时,它比原始代码快7倍左右:

from graphics import *

spacing = 1
zoom = 0.1

xOffset, yOffset = -0.171, 0.61

width, height = 700, 700

win = GraphWin('Mandelbrot', width, height, autoflush=False)

win.setBackground('black')

xzoom, yzoom = zoom / width, zoom / height

for real in range(0, width, spacing):

    ca = real * xzoom - xOffset

    for imaginary in range(0, height, spacing):

        c, z = complex(ca, imaginary * yzoom - yOffset), 0j

        n = 0

        while n < 10000:

            if abs(z) > 2000:
                break

            z = z * z + c

            n += 1

        color = 'black'

        if n > 5000:
            color = 'grey'
        elif n > 1000:
            color = 'white'

        if color != 'black':
            win.plot(real, imaginary, color=color)

    win.flush()
从图形导入*
间距=1
缩放=0.1
xOffset,yOffset=-0.171,0.61
宽度,高度=700700
win=GraphWin('Mandelbrot',宽度,高度,自动刷新=False)
胜利。挫折(“黑色”)
xzoom,yzoom=缩放/宽度,缩放/高度
对于范围内的实数(0、宽度、间距):
ca=实*xzoom-xOffset
对于虚拟范围(0、高度、间距):
c、 z=复数(ca,虚*yzoom-yOffset),0j
n=0
当n<10000时:
如果abs(z)>2000:
打破
z=z*z+c
n+=1
颜色=‘黑色’
如果n>5000:
颜色=‘灰色’
如果n>1000:
颜色=‘白色’
如果颜色!='黑色':
win.plot(真实、虚构、颜色=颜色)
同花顺
这并不是我们所希望的全部数量级,但是少7个小时的周转时间仍然是令人悲哀的


最后,您的代码中有一个bug,它阻止像素永远变灰——我已经修复了这个问题。

code
color=int(round(n/maxIterations*255))pt.setFill(color\u rgb(color,color,color,color))这是better@SamKinlochLarge,如何更好?我计时了,你的代码没有更快。OP的问题是关于速度,我的答案是关于速度。至于如何选择颜色,这取决于OP,这应该是对他的帖子的评论,而不是我的。很抱歉,这很公平