Mandelbrot Set(曼德勃罗集)可能是分形 图形中最有名的图形,关于它的介绍我就不多写了,有兴趣的可以参考这个链接 。下面是关于如何使用Python来画这个图形的尝试。
由于Python标准库中还没有对图形处理的支持,在此我使用了PIL 。先来看一张生成的图形:
相关的代码大致是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | # -*- coding: utf-8 -*- # # z<n+1> = z<n> ^ 2 + c # # by oldj # # last update: 2010-10-22 22:02:05 # import time import Image, ImageDraw g_size = ( 40 , 30 ) # 图形最终尺寸 g_max_iteration = 256 # 最大迭代次数 g_bailout = 4 # 最大域 g_zoom = 2.5 / g_size[ 0 ] # 缩放参数 g_offset = ( - g_size[ 0 ] * 0.25 , 0 ) # 偏移量 g_HSL = ( 210 , 80 , 50 ) # HSL色彩基调 def draw(antialias = True ): zi = 2 if antialias else 1 # antialias: 抗锯齿 size = [i * zi 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 Set.." for xy, color in getPoints(size, offset, zoom): dr.point(xy, fill = color) print "100%n" del dr if antialias: img = img.resize(g_size, Image.ANTIALIAS) img.show() img.save( "mandelbrot_set_%dx%d.png" % g_size) def getPoints(size, offset, zoom, ti = 0 , tstep = 1 ): "生成需要绘制的点的坐标及颜色" def getRepeats(c): z = c repeats = 0 while abs (z) < g_bailout and repeats < g_max_iteration: z = z * z + c repeats + = 1 return repeats def getColor(r): color = "hsl(0, 0%, 0%)" if r < g_max_iteration: v = 1.0 * r / g_max_iteration h = ch * ( 1 - v) s = cs l = cl * ( 1 + v) color = "hsl(%d, %d%%, %d%%)" % (h, s, l) return color xs, ys = size xw, yh = xs / 2 , ys / 2 xo, yo = offset ch, cs, cl = g_HSL progress = 0 for iy in xrange (ys): p = iy * 100 / ys if iy % 10 = = 0 and p ! = progress: print ( "%d%%..." % p) # 显示进度 progress = p for ix in xrange (ti, xs, tstep): x = (ix - xw + xo) * zoom y = (iy - yh + yo) * 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集始终有无穷无尽的变化与精致细节。