Advertisement
here2share

# Tk_Struct_Mandelbrot.py

Nov 14th, 2023
582
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.55 KB | None | 0 0
  1. # Tk_Struct_Mandelbrot.py
  2.  
  3. from tkinter import *
  4. from functools import lru_cache
  5. from PIL import Image, ImageTk
  6. import struct
  7.  
  8. ww = 200
  9. hh = 200
  10.  
  11. root = Tk()
  12. root.title("Tk_Struct_Mandelbrot")
  13. root.geometry('{}x{}'.format(ww * 2, hh))
  14.  
  15. canvas_main = Canvas(root, width=ww, height=hh)
  16. canvas_main.pack(side=LEFT, fill="both", expand=True)
  17.  
  18. canvas_debug = Canvas(root, width=ww, height=hh, bg='white')
  19. canvas_debug.pack(side=LEFT, fill="both", expand=True)
  20.  
  21. zoom_factor = 1.5
  22.  
  23. xRange = 1.0
  24. yRange = 1.0
  25. xOffset = 0
  26. yOffset = 0
  27. cx = ww // 2
  28. cy = hh // 2
  29. dx = dy = 0
  30.  
  31. precision = 400
  32.  
  33. def cache_mandelbrot(x0, y0):
  34.     struct_key = struct.pack('dd', x0, y0)
  35.     if struct_key in cache_mandelbrot.cache:
  36.         return cache_mandelbrot.cache[struct_key]
  37.  
  38.     x = 0.0
  39.     y = 0.0
  40.     k = 4000
  41.     for i in range(precision + 1):
  42.         x_new = x * x - y * y + x0
  43.         y = 2 * x * y + y0
  44.         x = x_new
  45.         if x * x + y * y > 10:
  46.             k = 12
  47.             break
  48.     j = (x * x + y * y) ** 0.5
  49.     j = int(i * (i * 10) + j * k) % Lr
  50.     result = rainbow[j]
  51.  
  52.     cache_mandelbrot.cache[struct_key] = result
  53.  
  54.     return result
  55.  
  56. cache_mandelbrot.cache = {}
  57.  
  58. def rgb2hex(rgb):
  59.     r, g, b = rgb
  60.     return "#{:02x}{:02x}{:02x}".format(r, g, b)
  61.  
  62. rainbow = []
  63. def z(r, g, b):
  64.     rainbow.append((r, g, b))
  65.  
  66. r, g, b = 255, 0, 0
  67. for g in range(256):
  68.     z(r, g, b)
  69. for r in range(254, -1, -1):
  70.     z(r, g, b)
  71. for b in range(256):
  72.     z(r, g, b)
  73. for g in range(254, -1, -1):
  74.     z(r, g, b)
  75. for r in range(256):
  76.     z(r, g, b)
  77. for b in range(254, -1, -1):
  78.     z(r, g, b)
  79. Lr = len(rainbow) - 1
  80.  
  81. img = Image.new('RGB', (ww, hh))
  82. pixels = img.load()
  83.  
  84. def calculate_mandelbrot(xRange, yRange):
  85.     canvas_debug.create_text(10, 20, anchor=NW, text="Processing, Please Wait...")
  86.     canvas_debug.update()
  87.     canvas_main.delete("all")
  88.     for row in range(hh):
  89.         for col in range(ww):
  90.             x0 = ((row - 50 - cx + dx + xOffset * xRange) * 3 / ww) / xRange
  91.             y0 = ((col - cy + dy + yOffset * yRange) * 2.5 / hh) / yRange
  92.             pixels[col, row] = cache_mandelbrot(x0, y0)
  93.     canvas_main.image = ImageTk.PhotoImage(img)
  94.     canvas_main.create_image(0, 0, anchor=NW, image=canvas_main.image)
  95.     update_debug_canvas()
  96.  
  97. def update_debug_canvas():
  98.     canvas_debug.delete("all")
  99.     canvas_debug.create_text(10, 50, anchor=NW, text=f"x offset: {xOffset*-1}")
  100.     canvas_debug.create_text(10, 70, anchor=NW, text=f"y offset: {yOffset*-1}")
  101.     canvas_debug.create_text(10, 90, anchor=NW, text=f"zoom_factor: {xRange}")
  102.  
  103. def on_mouse_down(event):
  104.     global drag_data
  105.     drag_data = {'x': event.x, 'y': event.y}
  106. def on_mouse_move(event):
  107.     global dx, dy
  108.     dx = (event.x - drag_data['x'])
  109.     dy = (event.y - drag_data['y'])
  110.     canvas_main.coords("all", dx, dy)
  111.     update_debug_canvas()
  112. def on_mouse_up(event):
  113.     global xOffset, yOffset, dx, dy
  114.     dx /= yRange
  115.     dy /= xRange
  116.     xOffset -= dy
  117.     yOffset -= dx
  118.     dx = dy = 0
  119.     calculate_mandelbrot(xRange, yRange)
  120.  
  121. def on_key_up(event):
  122.     global xRange, yRange
  123.     xRange, yRange = (xRange * zoom_factor, yRange * zoom_factor)
  124.     calculate_mandelbrot(xRange, yRange)
  125. def on_key_down(event):
  126.     global xRange, yRange
  127.     xRange, yRange = (xRange / zoom_factor, yRange / zoom_factor)
  128.     calculate_mandelbrot(xRange, yRange)
  129.  
  130. canvas_main.bind('<Button-1>', on_mouse_down)
  131. canvas_main.bind('<B1-Motion>', on_mouse_move)
  132. canvas_main.bind('<ButtonRelease-1>', on_mouse_up)
  133. root.bind('<Down>', on_key_down)
  134. root.bind('<Up>', on_key_up)
  135.  
  136. calculate_mandelbrot(xRange, yRange)
  137.  
  138. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement