Advertisement
here2share

# Tk_Cache_Mandelbrot.py

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