Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # tk_Rotating_Cube_Illusion.py
- ww, hh = 600, 600
- from tkinter import *
- import math
- import random
- import copy
- from PIL import Image, ImageDraw, ImageTk, ImageChops
- random.seed(0)
- def update_cube_coordinates():
- for i in range(8):
- x, y, z = rotated_coords[i][:3]
- coordinates[i] = get_coords(x , y, z)
- def get_coords(x, y, z):
- rxy = (x**2 + y**2)**(1/2)
- rxz = (x**2 + z**2)**(1/2)
- ryz = (y**2 + z**2)**(1/2)
- if x > 0 and y > 0:
- txy = math.atan(y/x)
- elif x > 0 and y < 0:
- txy = 2*math.pi + math.atan(y/x)
- elif x < 0 and y > 0:
- txy = math.pi + math.atan(y/x)
- elif x < 0 and y < 0:
- txy = math.pi + math.atan(y/x)
- if z > 0 and x > 0:
- txz = math.atan(x/z)
- elif z > 0 and x < 0:
- txz = 2*math.pi + math.atan(x/z)
- elif z < 0 and x > 0:
- txz = math.pi + math.atan(x/z)
- elif z < 0 and x < 0:
- txz = math.pi + math.atan(x/z)
- if y > 0 and z > 0:
- tyz = math.atan(z/y)
- elif y > 0 and z < 0:
- tyz = 2*math.pi + math.atan(z/y)
- elif y < 0 and z > 0:
- tyz = math.pi + math.atan(z/y)
- elif y < 0 and z < 0:
- tyz = math.pi + math.atan(z/y)
- return x, y, z, rxy, rxz, ryz, txy, txz, tyz
- def rotate_z(coord, t):
- txy = coord[6] + t if coord[6] + t >= 0 else coord[6] + t + 2*math.pi
- x = math.cos(txy) * coord[3]
- y = math.sin(txy) * coord[3]
- return get_coords(x, y, coord[2])
- def rotate_y(coord, t):
- txz = coord[7] + t if coord[7] + t >= 0 else coord[7] + t + 2*math.pi
- z = math.cos(txz) * coord[4]
- x = math.sin(txz) * coord[4]
- return get_coords(x, coord[1], z)
- def rotate_x(coord, t):
- tyz = coord[8] + t if coord[8] + t >= 0 else coord[8] + t + 2*math.pi
- y = math.cos(tyz) * coord[5]
- z = math.sin(tyz) * coord[5]
- return get_coords(coord[0], y, z)
- rotation_speeds = {}
- def rotation():
- rotation_speeds["X"] = random.uniform(0.02, 0.05) * random.choice((1, -1))
- rotation_speeds["Y"] = random.uniform(0.02, 0.05) * random.choice((1, -1))
- rotation_speeds["Z"] = random.uniform(0.02, 0.05) * random.choice((1, -1))
- rotation()
- def alias_line(x1, y1, x2, y2):
- num_squares = int(max(abs(x2 - x1), abs(y2 - y1))) or 1
- for i in range(0, num_squares + 1, sq):
- x = (x1 + i * (x2 - x1) // num_squares) // sq * sq
- y = (y1 + i * (y2 - y1) // num_squares) // sq * sq
- try:
- if img.getpixel((x + 2, y + 2)) != (0, 0, 0):
- pos, color = xy[x, y, 'b']
- else:
- pos, color = xy[x, y]
- draw.rectangle(pos, outline=None, fill=color)
- except:
- 0
- def plot():
- for i in range(4):
- alias_line(rotated_coords[i][0] * Vz/dd + Vx, rotated_coords[i][2] * Vz/dd + Vy,
- rotated_coords[(i + 1) % 4][0] * Vz/dd + Vx, rotated_coords[(i + 1) % 4][2] * Vz/dd + Vy)
- alias_line(rotated_coords[i + 4][0] * Vz/dd + Vx, rotated_coords[i + 4][2] * Vz/dd + Vy,
- rotated_coords[((i + 1) % 4) + 4][0] * Vz/dd + Vx, rotated_coords[((i + 1) % 4) + 4][2] * Vz/dd + Vy)
- alias_line(rotated_coords[i][0] * Vz/dd + Vx, rotated_coords[i][2] * Vz/dd + Vy,
- rotated_coords[i + 4][0] * Vz/dd + Vx, rotated_coords[i + 4][2] * Vz/dd + Vy)
- ww, hh = 640, 640
- dd = 600
- sz = 100
- xSpeed = 5.7
- ySpeed = 7.8
- zSpeed = 9.9
- Vx = ww/2
- Vy = hh/2
- Vz = 1000
- bd = 10
- sq = 5
- coordinates = [
- get_coords(sz, sz, -sz), get_coords(-sz, sz, -sz), get_coords(-sz, sz, sz), get_coords(sz, sz, sz),
- get_coords(sz, -sz, -sz), get_coords(-sz, -sz, -sz), get_coords(-sz, -sz, sz), get_coords(sz, -sz, sz)
- ]
- win = Tk()
- win.title("# tk_Rotating_Cube_Illusion")
- win.geometry("%dx%d+%d+%d" %(ww, hh, 10, 10))
- C = Canvas(win, width=ww, height=hh)
- C.pack()
- img = Image.new("RGB", (ww, hh), "white")
- draw = ImageDraw.Draw(img)
- for x in range(-2, 3):
- for y in range(-2, 3):
- C.create_text(x + ww // 2, y + 50, text="PRESS SPACEBAR", fill="white", font=("Arial", 40, "bold"), anchor="center", tag="hideable_text")
- C.create_text(ww // 2, 50, text="PRESS SPACEBAR", fill="red", font=("Arial", 40, "bold"), anchor="center", tag="hideable_text")
- def blink_text():
- current_state = "normal" if C.itemcget("hideable_text", "state") == "hidden" else "hidden"
- C.itemconfig("hideable_text", state=current_state)
- C.tag_raise("hideable_text")
- win.after(1000, blink_text)
- xy = {}
- for i in range(0, ww, sq):
- for j in range(0, hh, sq):
- pos = [i, j, i + sq - 1, j + sq - 1]
- xy[i, j] = (pos, "white")
- xy[i, j, 'b'] = (pos, "black")
- draw.rectangle(pos, outline=None, fill=random.choice(('black', 'white')))
- sp = 0.01
- rotate = {
- "q": ("X", sp),
- "w": ("X", -sp),
- "e": ("Y", sp),
- "a": ("Y", -sp),
- "s": ("Z", sp),
- "d": ("Z", -sp),
- }
- def key_rotate(axis, t):
- rotation_speeds[axis] = t
- for k, (axis, t) in rotate.items():
- win.bind(f"<Key-{k}>", lambda event, axis=axis, t=t: key_rotate(axis, t))
- def toggle_pause(event):
- global is_paused
- is_paused = not is_paused
- blink_text()
- win.bind("<space>", toggle_pause)
- is_paused = False
- while True:
- if not is_paused:
- rotated_coords = []
- for i in range(8):
- rotated_coords.append(rotate_x(coordinates[i], rotation_speeds["X"]))
- rotated_coords[i] = rotate_y(rotated_coords[i], rotation_speeds["Y"])
- rotated_coords[i] = rotate_z(rotated_coords[i], rotation_speeds["Z"])
- plot()
- update_cube_coordinates()
- imgtk = ImageTk.PhotoImage(img)
- C.create_image(0, 0, anchor=NW, image=imgtk)
- C.tag_raise("hideable_text")
- at_wall = 0
- if Vx < -bd:
- xSpeed = abs(xSpeed)
- at_wall = 1
- elif Vx > ww + bd:
- xSpeed = -abs(xSpeed)
- at_wall = 1
- if Vy < -bd:
- ySpeed = abs(ySpeed)
- at_wall = 1
- elif Vy > hh + bd:
- ySpeed = -abs(ySpeed)
- at_wall = 1
- if Vz < 800:
- zSpeed = abs(zSpeed)
- at_wall = 1
- elif Vz > 1800:
- zSpeed = -abs(zSpeed)
- at_wall = 1
- if at_wall:
- rotation()
- Vx += xSpeed
- Vy += ySpeed
- Vz += zSpeed
- win.update()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement