Python Tkinter实现的Mandelbrot集比C版本精度更高,原因何在?
Python与C语言Mandelbrot集实现的差异原因
用Python结合Tkinter的PhotoImage绘制Mandelbrot集,参数为256次迭代、256色自定义调色板,得到的图像带有长丝状结构且无迭代限制间的同心边界;但用C语言复现相同参数后,图像却是短丝状结构,还存在迭代逃逸值间的同心边界。核心差异点及原因如下:

1. 逃逸判断条件完全不同
这是导致图像差异的最关键原因:
- Python代码的逃逸判断:
在mandel_pixel函数中,每次迭代计算a = z * z,然后判断a.real > 4.时返回当前迭代次数i。这里判断的是z的平方的实部大于4,而非标准Mandelbrot集的|z| > 2(即x² + y² >4)。 - C代码的逃逸判断:
循环条件是((x*x+y*y)<4.),也就是标准的**|z|² <4**(即|z|<2),当该条件不满足时停止迭代。
这两个条件并不等价:
比如当z=1.5+1.5i时,|z|²=4.5>4,满足C的逃逸条件,但z²=4.5i,实部为0,不满足Python的逃逸条件,会继续迭代;反之,若z=3i,z²=-9,实部小于4,不触发Python的逃逸,但|z|²=9>4,会触发C的逃逸。这种判断逻辑的差异直接导致了迭代终止时机不同,最终呈现的丝状结构长度、边界特征完全不同。
2. 迭代计数起始值差异
- Python的循环是
for i in range(maxIt),i从0开始计数,第一次迭代对应i=0; - C代码的循环从i=1开始计数,第一次迭代对应i=1。
这会导致两者返回的迭代次数差1,虽然对整体结构影响小于逃逸条件,但会影响颜色映射的细节。
3. 代码实现细节对比
Python完整代码
# by Antoni Gual Via 4/2015 from tkinter import Tk, Canvas, PhotoImage,NW,mainloop from time import time def mandel_pixel(c): #c is a complex """ calculates the color index of the mandelbrot plane point passed in the arguments """ maxIt = 256 z = c for i in range(maxIt): a = z * z z=a + c if a.real > 4.: return i return maxIt def mandelbrot(xa,xb,ya,yb,x,y): """ returns a mandelbrot in a string for Tk PhotoImage""" #color string table in Photoimage format #RRGGBB clr=[ ' #%02x%02x%02x' % (int(255*((i/255)**.25)),0,0) for i in range(256)] clr.append(' #000000') #append the color of the centre as index 256 #calculate mandelbrot x,y coordinates for each screen pixel xm=list([xa + (xb - xa) * kx /x for kx in range(x)]) ym=list([ya + (yb - ya) * ky /y for ky in range(y)]) #build the Photoimage string by calling mandel_pixel to index in the color table return " ".join(("{"+"".join(clr[mandel_pixel(complex(i,j))] for i in xm))+"}" for j in ym)) #window size x=640 y=480 #corners of the complex plane to display xa = -2.0; xb = 1.0 ya = -1.27; yb = 1.27 #Tkinter window window = Tk() canvas = Canvas(window, width = x, height = y, bg = "#000000");canvas.pack() img = PhotoImage(width = x, height = y) canvas.create_image((0, 0), image = img, state = "normal", anchor = NW) #do the mandelbrot print('Starting Mandelbrot') t1=time() img.put(mandelbrot(xa,xb,ya,yb,x,y)) print(time()-t1, ' seconds') mainloop()
C代码核心部分
int mandel(double x0,double y0, int maxit){ double x=x0, xt=0.; double y=y0; int i; for (i=1;((x*x+y*y)<4.) && (i<=maxit);i++){ xt=x*x-y*y+x0; y=2.*x*y+y0; x=xt ; } return(i<maxit ? rgb(255.*(pow(((double)i/maxit),.25)),0,0):0); }
内容的提问来源于stack exchange,提问作者Antoni Gual Via
相关产品推荐
相关产品推荐

