2017-08-12 67 views
1

我用Mandelbrot程序寫入圖像時遇到了問題;它與「(maxx-minx)/ width」與「(maxy-miny)/ width」第31行的舍入誤差相關,這導致501乘500圖片而不是500圖片。 ((寬度+ 1)*長度)不是(寬度*長度)。 我該如何解決這個問題?用PIL舍入錯誤

from PIL import Image 
from cmath import * 
from math import sqrt 
from numpy import arange 

width = 500 
height = 500 

minx = -0.752 #float(input("Please enter the minimum x value:")) 
maxx = -0.748 #float(input("Please enter the maximum x value:")) 
miny = 0.098 #float(input("Please enter the minimum y value:")) 
maxy = 0.102 #float(input("Please enter the maximum y value:")) 

gradient = Image.open("mandelbrot.png") 
gradlist = list(gradient.getdata()) 

def testMandelbrot(x, y): 
    z = 0 + 0j 
    c = x + (y*1j) 
    iter = 0 
    while iter <= 69 and sqrt(z.real**2 + z.imag**2) < 4: 
     z = (z*z) + c 
     iter += 1 
    if iter == 70: 
     return (0, 0, 0, 255) 
    else: 
     return gradlist[int((iter - 1) * 140/70)] 

img = Image.new('RGBA', (width, height), color=(255, 255, 255, 255)) 
image = [testMandelbrot(x, y) for y in arange(miny, maxy, (maxy-miny)/height) for x in arange(minx, maxx, (maxx-minx)/width)] #this line creates the error ((maxx-minx)/width)/(maxx - min) gives (width+1) not width 
print(len(image), img.size) 
img.putdata(image) 
img.save("picture111.png", "PNG") 
+0

我已經測試過試圖強制舍入值,但這會使舍入誤差變得更糟。我該怎麼辦? –

回答

2

我建議使用numpy's linspace而非arange。它將返回一個確切數量的均勻間隔樣本數組。

看到linspace(0.098, 0.102, 500, endpoint=False)正好是500點長。如果要包含端點,則可以省略endpoint=False或通過endpoint=True

隨着endpoint=False如果生成具有相同尺寸的高度和寬度的另一圖像,但max_ - min_之間通過差抵消,結果將是取決於其將導致8之一的鄰近瓦片。然後

您的代碼將是:

Y = linspace(miny, maxy, height, endpoint=False) 
X = linspace(minx, maxx, width, endpoint=False) 
image = [testMandelbrot(x, y) for y in Y for x in X] 

我命名的陣列,因爲Y被重用len(X)倍,由於高度和寬度都小(500),它不花費太多,教具可讀性。

+0

非常感謝 - 這解決了我的問題。 –