Mandelbrot Set(曼德勃罗集)可能是分形 图形中最有名的图形,关于它的介绍我就不多写了,有兴趣的可以参考这个链接 。下面是关于如何使用Python来画这个图形的尝试。
由于Python标准库中还没有对图形处理的支持,在此我使用了PIL 。先来看一张生成的图形:
相关的代码大致是这样的:
import time
import Image, ImageDraw
g_size = (600, 450) # 图形最终尺寸
g_maxIteration = 256 # 最大迭代次数
g_bailout = 4 # 最大域
g_zoom = 2.5 / g_size[0] # 缩放参数
g_offset = (-g_size[0] * 0.25, 0) # 偏移量
def draw(antialias = True):
zi = 1
if antialias: # 抗锯齿
zi = 2
size = [i * zi for i in g_size]
zoom = g_zoom / zi
offset = [i * zi for i in g_offset]
bailout = g_bailout * zi
img = Image.new("RGB", size, 0xffffff)
dr = ImageDraw.Draw(img)
print "painting Mandelbrot .."
for p in getPoints(size, offset, zoom):
dr.point(p[0], fill = p[1])
print "%s100%%" % ("/b" * 10)
del dr
if antialias:
img = img.resize(g_size, Image.ANTIALIAS)
# img.show()
img.save("mandelbrot.png")
def getPoints(size, offset, zoom, ti = 0, tstep = 1):
"生成需要绘制的点的坐标及颜色"
def getRepeats(c):
z = c
repeats = 0
while abs(z) < g_bailout and repeats < g_maxIteration:
z = z ** 2 + c
repeats += 1
return repeats
def getColor(r):
color = "hsl(0, 0%, 0%)"
if r < g_maxIteration:
v = 1.0 * r / g_maxIteration
h = 210 * (1 - v)
s = 80
l = 50 * (1 + v)
color = "hsl(%d, %d%%, %d%%)" % (h, s, l)
return color
xs, ys = size
for iy in xrange(ys):
print ("%s%d%%..." % ("/b" * 10, iy * 100 / ys)),
for ix in xrange(ti, xs, tstep):
x = (ix - xs / 2 + offset[0]) * zoom
y = (iy - ys / 2 + offset[1]) * zoom
c = complex(x, y)
r = getRepeats(c)
yield (ix, iy), getColor(r)
def main():
t0 = time.time()
draw()
t = time.time() - t0
print "%dm%.3fs" % (t / 60, t % 60)
if __name__ == "__main__":
main()
其中第8行设置了图形最终的尺寸,如果想生成大一些或小一些的图形,可以修改这个参数。第9行是最大迭代次数,这个参数值越高越能得到更多的图像细节,当然,代价就是需要更多的计算时间。
另外,第47~55行的getColor函数定义了每个点颜色的产生规则,可以在这儿修改颜色规则,画出更多不同色彩的Mandelbrot集来。
下面是本程序在不同的参数及颜色规则下生成的另外几副图。
修改一下上面的代码,不难生成更多细节图片。不过,如果不想自己动手,也可以试一下XaoS 这个软件,通过它,你可以将Mandelbrot集的某个局部放大很多倍。当然,你会发现,无论放大了多少,Mandelbrot集始终有无穷无尽的变化与精致细节。