Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # 3D_illusion_pentagon.py
- import tkinter as tk
- import math
- from PIL import Image, ImageDraw, ImageTk
- WW = HH = 600
- n = 32
- center_x, center_y = WW / 2, HH / 2
- pentagon_radius = 210
- root = tk.Tk()
- root.title("# 3D_illusion_pentagon.py")
- root.geometry(f"{WW}x{HH}+0+0")
- canvas = tk.Canvas(root, width=WW, height=HH, bg="white")
- canvas.pack()
- def hsv_to_hex(h, s, v):
- i = int(h * 6)
- f = h * 6 - i
- p = v * (1 - s)
- q = v * (1 - f * s)
- t = v * (1 - (1 - f) * s)
- i %= 6
- if i == 0:
- r, g, b = v, t, p
- elif i == 1:
- r, g, b = q, v, p
- elif i == 2:
- r, g, b = p, v, t
- elif i == 3:
- r, g, b = p, q, v
- elif i == 4:
- r, g, b = t, p, v
- else:
- r, g, b = v, p, q
- return "#%02x%02x%02x" % (int(r * 255), int(g * 255), int(b * 255))
- def get_rotated_square_points(cx, cy, size, angle):
- half = size / 2
- corners = [(-half, -half), (half, -half), (half, half), (-half, half)]
- pts = []
- cos_a = math.cos(angle)
- sin_a = math.sin(angle)
- for x, y in corners:
- x_rot = x * cos_a - y * sin_a
- y_rot = x * sin_a + y * cos_a
- pts.extend([cx + x_rot, cy + y_rot])
- return pts
- pentagon = []
- for i in range(5):
- angle = -math.pi / 2 + i * (2 * math.pi / 5)
- x = center_x + pentagon_radius * math.cos(angle)
- y = center_y + pentagon_radius * math.sin(angle)
- pentagon.append((x, y))
- squares = []
- total = n * 5
- colors = [hsv_to_hex(i / total * 2, 1, 1) for i in range(total)]
- col_idx = 0
- for i in range(5):
- A = pentagon[i]
- B = pentagon[(i + 1) % 5]
- for j in range(n):
- t = (j + 0.5) / n
- x = A[0] + (B[0] - A[0]) * t
- y = A[1] + (B[1] - A[1]) * t
- dx = x - center_x
- dy = y - center_y
- orbit_radius = math.hypot(dx, dy)
- orbit_angle = math.atan2(dy, dx)
- squares.append({
- 'orbit_radius': orbit_radius,
- 'orbit_angle': orbit_angle,
- 'self_angle': 0,
- 'orbit_speed': 0.025,
- 'self_speed': 0.07,
- 'color': colors[col_idx]
- })
- col_idx += 1
- blank = Image.new("RGBA", (WW, HH), (0, 0, 0, 0))
- def update():
- img = Image.new("RGBA", (WW, HH), "white")
- draw = ImageDraw.Draw(img)
- pts = {}
- for idx, sq in enumerate(squares):
- sq['orbit_angle'] += sq['orbit_speed']
- sq['self_angle'] += sq['self_speed']
- cx = center_x + sq['orbit_radius'] * math.cos(sq['orbit_angle'])
- cy = center_y + sq['orbit_radius'] * math.sin(sq['orbit_angle'])
- pts[idx] = get_rotated_square_points(cx, cy, 100, sq['self_angle'])
- draw.polygon(pts[idx], fill=sq['color'], outline="white")
- if idx == n * 4:
- mask = Image.new("L", (WW, HH), 0) # Black mask by default
- mask_draw = ImageDraw.Draw(mask)
- for idx in range(0, 10):
- mask_draw.polygon(pts[idx], fill=255) # White where we want to grab the region
- grabbed_region = Image.composite(img, blank, mask)
- img.paste(grabbed_region, (0, 0), grabbed_region)
- photo = ImageTk.PhotoImage(img)
- canvas.create_image(0, 0, anchor=tk.NW, image=photo)
- canvas.image = photo
- root.after(1, update)
- update()
- root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement