Advertisement
here2share

# 3D_illusion_pentagon.py

Feb 6th, 2025
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.17 KB | None | 0 0
  1. # 3D_illusion_pentagon.py
  2.  
  3. import tkinter as tk
  4. import math
  5. from PIL import Image, ImageDraw, ImageTk
  6.  
  7. WW = HH = 600
  8. n = 32
  9. center_x, center_y = WW / 2, HH / 2
  10. pentagon_radius = 210
  11.  
  12. root = tk.Tk()
  13. root.title("# 3D_illusion_pentagon.py")
  14. root.geometry(f"{WW}x{HH}+0+0")
  15. canvas = tk.Canvas(root, width=WW, height=HH, bg="white")
  16. canvas.pack()
  17.  
  18. def hsv_to_hex(h, s, v):
  19.     i = int(h * 6)
  20.     f = h * 6 - i
  21.     p = v * (1 - s)
  22.     q = v * (1 - f * s)
  23.     t = v * (1 - (1 - f) * s)
  24.     i %= 6
  25.     if i == 0:
  26.         r, g, b = v, t, p
  27.     elif i == 1:
  28.         r, g, b = q, v, p
  29.     elif i == 2:
  30.         r, g, b = p, v, t
  31.     elif i == 3:
  32.         r, g, b = p, q, v
  33.     elif i == 4:
  34.         r, g, b = t, p, v
  35.     else:
  36.         r, g, b = v, p, q
  37.     return "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255))
  38.  
  39. def get_rotated_square_points(cx, cy, size, angle):
  40.     half = size / 2
  41.     corners = [(-half, -half), (half, -half), (half, half), (-half, half)]
  42.     pts = []
  43.     cos_a = math.cos(angle)
  44.     sin_a = math.sin(angle)
  45.     for x, y in corners:
  46.         x_rot = x * cos_a - y * sin_a
  47.         y_rot = x * sin_a + y * cos_a
  48.         pts.extend([cx + x_rot, cy + y_rot])
  49.     return pts
  50.  
  51. pentagon = []
  52. for i in range(5):
  53.     angle = -math.pi / 2 + i * (2 * math.pi / 5)
  54.     x = center_x + pentagon_radius * math.cos(angle)
  55.     y = center_y + pentagon_radius * math.sin(angle)
  56.     pentagon.append((x, y))
  57.  
  58. squares = []
  59. total = n * 5
  60. colors = [hsv_to_hex(i / total * 2, 1, 1) for i in range(total)]
  61. col_idx = 0
  62.  
  63. for i in range(5):
  64.     A = pentagon[i]
  65.     B = pentagon[(i + 1) % 5]
  66.     for j in range(n):
  67.         t = (j + 0.5) / n
  68.         x = A[0] + (B[0] - A[0]) * t
  69.         y = A[1] + (B[1] - A[1]) * t
  70.         dx = x - center_x
  71.         dy = y - center_y
  72.         orbit_radius = math.hypot(dx, dy)
  73.         orbit_angle = math.atan2(dy, dx)
  74.         squares.append({
  75.             'orbit_radius': orbit_radius,
  76.             'orbit_angle': orbit_angle,
  77.             'self_angle': 0,
  78.             'orbit_speed': 0.025,
  79.             'self_speed': 0.07,
  80.             'color': colors[col_idx]
  81.         })
  82.         col_idx += 1
  83.  
  84. blank = Image.new("RGBA", (WW, HH), (0, 0, 0, 0))
  85. def update():
  86.     img = Image.new("RGBA", (WW, HH), "white")
  87.     draw = ImageDraw.Draw(img)
  88.  
  89.     pts = {}
  90.     for idx, sq in enumerate(squares):
  91.         sq['orbit_angle'] += sq['orbit_speed']
  92.         sq['self_angle'] += sq['self_speed']
  93.         cx = center_x + sq['orbit_radius'] * math.cos(sq['orbit_angle'])
  94.         cy = center_y + sq['orbit_radius'] * math.sin(sq['orbit_angle'])
  95.         pts[idx] = get_rotated_square_points(cx, cy, 100, sq['self_angle'])
  96.         draw.polygon(pts[idx], fill=sq['color'], outline="white")
  97.         if idx == n * 4:
  98.             mask = Image.new("L", (WW, HH), 0)  # Black mask by default
  99.             mask_draw = ImageDraw.Draw(mask)
  100.             for idx in range(0, 10):
  101.                 mask_draw.polygon(pts[idx], fill=255)  # White where we want to grab the region
  102.  
  103.             grabbed_region = Image.composite(img, blank, mask)
  104.  
  105.     img.paste(grabbed_region, (0, 0), grabbed_region)
  106.  
  107.     photo = ImageTk.PhotoImage(img)
  108.     canvas.create_image(0, 0, anchor=tk.NW, image=photo)
  109.     canvas.image = photo
  110.  
  111.     root.after(1, update)
  112.  
  113. update()
  114. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement