2009-02-07 44 views
5

Tôi đã tạo một tệp Python để tạo một tập hợp hình ảnh Mandelbrot. Mã toán học ban đầu không phải của tôi, vì vậy tôi không hiểu nó - Tôi chỉ sửa đổi nó rất nhiều để làm cho nó nhanh hơn khoảng 250 lần (Quy tắc chủ đề!).Làm cách nào để 'phóng to' trên một phần của tập hợp Mandelbrot?

Dù sao, tôi đã tự hỏi làm thế nào tôi có thể sửa đổi phần toán học của mã để làm cho nó hiển thị một bit cụ thể. Đây là toán học phần:

for y in xrange(size[1]): 
     coords = (uleft[0] + (x/size[0]) * (xwidth),uleft[1] - (y/size[1]) * (ywidth)) 
     z = complex(coords[0],coords[1]) 
     o = complex(0,0) 
     dotcolor = 0 # default, convergent 
     for trials in xrange(n): 
      if abs(o) <= 2.0: 
       o = o**2 + z 
      else: 
       dotcolor = trials 
       break # diverged 
     im.putpixel((x,y),dotcolor) 

Và các định nghĩa kích thước:

size1 = 500 
size2 = 500 
n=64 
box=((-2,1.25),(0.5,-1.25)) 
plus = size[1]+size[0] 
uleft = box[0] 
lright = box[1] 
xwidth = lright[0] - uleft[0] 
ywidth = uleft[1] - lright[1] 

những gì tôi cần phải sửa đổi để làm cho nó render một phần nhất định của tập?

+0

Tôi nhớ cách bạn sử dụng các chủ đề để làm cho mã nhanh hơn, vì python bytecod e trên các chủ đề sẽ không thực thi đồng thời vì GIL. – nosklo

Trả lời

14

Dòng:

box=((-2,1.25),(0.5,-1.25)) 

là bit xác định khu vực có toạ độ không gian đang được trả lại, vì vậy bạn chỉ cần thay đổi dòng này. Cặp tọa độ đầu tiên là phần trên cùng bên trái của khu vực, thứ hai là góc dưới cùng bên phải.

Để có tọa độ mới từ hình ảnh phải khá đơn giản. Bạn có hai hệ tọa độ, hệ thống "hình ảnh" của bạn có kích thước 100x100 pixel, có nguồn gốc tại (0,0). Và hệ thống tọa độ mặt phẳng "phức tạp" của bạn được xác định bởi "hộp". Đối với X:

X_complex=X_complex_origin+(X_image/X_image_width)*X_complex_width 
+0

Cảm ơn người đàn ông! Làm thế nào tôi có thể chuyển đổi các giá trị này thành X và Y? Có thể không? – Lobe

+0

Hộp chứa hai cặp x, y: hộp = ((x, y), (x, y)) Có phải câu trả lời cho câu hỏi của bạn không? –

+0

Ahh, xin lỗi về điều đó, tôi đã nhận được kết thúc sai của cây gậy. Ý tôi là, nếu tôi có kích thước của hình ảnh được hiển thị đầy đủ (Nói 100x100), làm cách nào tôi có thể chuyển đổi giá trị x và y của một phần của hình ảnh 100x100 thành giá trị x và y để 'phóng to' ở trên? Tôi nghi ngờ nó có thể - và cảm ơn bạn đã trả lời! – Lobe

4

Mấu chốt trong việc tìm hiểu làm thế nào để làm điều này là để hiểu những gì dòng coords = được thực hiện:

coords = (uleft[0] + (x/size[0]) * (xwidth),uleft[1] - (y/size[1]) * (ywidth)) 

có hiệu quả, các xy giá trị bạn đang Looping qua tương ứng với các tọa độ của điểm ảnh trên màn hình đang được dịch sang điểm tương ứng trên mặt phẳng phức tạp đang được xem xét. Điều này có nghĩa là tọa độ màn hình (0,0) sẽ dịch sang khu vực phía trên bên trái được xem là (-2,1.25)(1,0) sẽ giống nhau, nhưng đã di chuyển 1/500 khoảng cách (giả sử cửa sổ chiều rộng 500 pixel) giữa tọa độ -20.5.

Đó là chính xác những gì dòng đó đang làm - Tôi sẽ mở rộng chỉ các bit X-phối hợp với tên biến minh họa hơn để cho biết điều này:

mandel_x = mandel_start_x + (screen_x/screen_width) * mandel_width 

(Các mandel_ biến tham khảo các tọa độ trên máy bay phức tạp , các biến số screen_ tham chiếu đến tọa độ trên màn hình của điểm ảnh đang được vẽ.)

Nếu bạn muốn sau đó lấy vùng màn hình để phóng to, bạn muốn thực hiện chính xác như cũ: lấy tọa độ màn hình của vùng trên bên trái và dưới bên phải, dịch chúng sang coor mặt phẳng phức tạp chấm dứt, và biến chúng thành các biến uleft và lright mới. tức là để phóng to trên hộp giới hạn bởi các tọa độ trên màn hình (x1, y1) .. (x2, y2), sử dụng:

new_uleft = (uleft[0] + (x1/size[0]) * (xwidth), uleft[1] - (y1/size[1]) * (ywidth)) 
new_lright = (uleft[0] + (x2/size[0]) * (xwidth), uleft[1] - (y2/size[1]) * (ywidth)) 

(Rõ ràng bạn sẽ cần phải tính toán lại kích thước, xwidth, ywidth và các biến phụ thuộc khác dựa trên tọa độ mới)

Trong trường hợp bạn tò mò, các toán học đằng sau bộ mandelbrot không phức tạp (chỉ phức tạp). Tất cả những gì nó đang làm là lấy một tọa độ cụ thể, xử lý nó như một số phức, và sau đó lặp lại bình phương nó và thêm số ban đầu vào nó.

Đối với một số con số, làm điều này sẽ làm cho kết quả phân kỳ, liên tục phát triển theo hướng vô cùng khi bạn lặp lại quy trình. Đối với những người khác, nó sẽ luôn luôn ở dưới một mức độ nhất định (ví dụ, rõ ràng là (0,0, 0,0) không bao giờ nhận được bất kỳ lớn hơn theo quá trình này.Mandelbrot bộ (vùng màu đen) là những tọa độ mà không phân kỳ. bất kỳ số nào nằm trên căn bậc hai của 5, nó sẽ phân tách - mã của bạn chỉ sử dụng 2.0 là xấp xỉ của nó là sqrt(5) (~ 2.236), nhưng điều này sẽ không tạo ra sự khác biệt đáng chú ý. được vẽ với số lần lặp lại của quá trình mà chúng cần để chúng vượt quá giá trị này (biến số trials trong mã của bạn), đó là những gì tạo ra các vùng màu.

Các vấn đề liên quan