# # tk_3D_Cube.py

Feb 12th, 2024 (edited)
958
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. # tk_3D_Cube.py -- revised
2.
3. ww, hh = 600, 600
4.
5. from tkinter import *
6. import math
7. import random
8.
9. def update_cube_coordinates():
10.     for i in range(8):
11.         x, y, z = rotated_coords[i][:3]
12.         coordinates[i] = get_coords(x , y, z)
13.
14. def get_coords(x, y, z):
15.     rxy = (x**2 + y**2)**(1/2)
16.     rxz = (x**2 + z**2)**(1/2)
17.     ryz = (y**2 + z**2)**(1/2)
18.
19.     if x > 0 and y > 0:
20.         txy = math.atan(y/x)
21.     elif x > 0 and y < 0:
22.         txy = 2*math.pi + math.atan(y/x)
23.     elif x < 0 and y > 0:
24.         txy = math.pi + math.atan(y/x)
25.     elif x < 0 and y < 0:
26.         txy = math.pi + math.atan(y/x)
27.
28.     if z > 0 and x > 0:
29.         txz = math.atan(x/z)
30.     elif z > 0 and x < 0:
31.         txz = 2*math.pi + math.atan(x/z)
32.     elif z < 0 and x > 0:
33.         txz = math.pi + math.atan(x/z)
34.     elif z < 0 and x < 0:
35.         txz = math.pi + math.atan(x/z)
36.
37.     if y > 0 and z > 0:
38.         tyz = math.atan(z/y)
39.     elif y > 0 and z < 0:
40.         tyz = 2*math.pi + math.atan(z/y)
41.     elif y < 0 and z > 0:
42.         tyz = math.pi + math.atan(z/y)
43.     elif y < 0 and z < 0:
44.         tyz = math.pi + math.atan(z/y)
45.
46.     return x, y, z, rxy, rxz, ryz, txy, txz, tyz
47.
48. def rotate_z(coord, t):
49.     txy = coord[6] + t if coord[6] + t >= 0 else coord[6] + t + 2*math.pi
50.     x = math.cos(txy) * coord[3]
51.     y = math.sin(txy) * coord[3]
52.     return get_coords(x, y, coord[2])
53.
54. def rotate_y(coord, t):
55.     txz = coord[7] + t if coord[7] + t >= 0 else coord[7] + t + 2*math.pi
56.     z = math.cos(txz) * coord[4]
57.     x = math.sin(txz) * coord[4]
58.     return get_coords(x, coord[1], z)
59.
60. def rotate_x(coord, t):
61.     tyz = coord[8] + t if coord[8] + t >= 0 else coord[8] + t + 2*math.pi
62.     y = math.cos(tyz) * coord[5]
63.     z = math.sin(tyz) * coord[5]
64.     return get_coords(coord[0], y, z)
65.
66. rotation_speeds = {}
67. def rotation():
68.     rotation_speeds["X"] = random.uniform(0.002, 0.005) * random.choice((1, -1))
69.     rotation_speeds["Y"] = random.uniform(0.002, 0.005) * random.choice((1, -1))
70.     rotation_speeds["Z"] = random.uniform(0.002, 0.005) * random.choice((1, -1))
71. rotation()
72.
73. def plot():
74.     for i in range(4):
75.         id_ = C.create_line(rotated_coords[i][0] * Vz/dd + Vx, rotated_coords[i][2] * Vz/dd + Vy,
76.                              rotated_coords[(i + 1) % 4][0] * Vz/dd + Vx, rotated_coords[(i + 1) % 4][2] * Vz/dd + Vy)
77.         C.itemconfig(id_, width=3)
78.
79.         id_ = C.create_line(rotated_coords[i + 4][0] * Vz/dd + Vx, rotated_coords[i + 4][2] * Vz/dd + Vy,
80.                              rotated_coords[((i + 1) % 4) + 4][0] * Vz/dd + Vx, rotated_coords[((i + 1) % 4) + 4][2] * Vz/dd + Vy)
81.         C.itemconfig(id_, width=3)
82.
83.         id_ = C.create_line(rotated_coords[i][0] * Vz/dd + Vx, rotated_coords[i][2] * Vz/dd + Vy,
84.                              rotated_coords[i + 4][0] * Vz/dd + Vx, rotated_coords[i + 4][2] * Vz/dd + Vy)
85.         C.itemconfig(id_, width=3)
86.
87.
88. ww, hh = 600, 600
89. dd = 600
90. sz = 100
91. xSpeed = 0.3
92. ySpeed = 0.5
93. zSpeed = 0.4
94. Vx = ww/2
95. Vy = hh/2
96. Vz = 700
97. bd = 10
98.
99. coordinates = [
100.     get_coords(sz, sz, -sz), get_coords(-sz, sz, -sz), get_coords(-sz, sz, sz), get_coords(sz, sz, sz),
101.     get_coords(sz, -sz, -sz), get_coords(-sz, -sz, -sz), get_coords(-sz, -sz, sz), get_coords(sz, -sz, sz)
102. ]
103.
104. win = Tk()
105. win.title("tk_3D_Cube")
106.
107. C = Canvas(win, width=ww, height=hh)
108. C.pack()
109.
110. sp = 0.01
111. rotate = {
112.     "q": ("X", sp),
113.     "w": ("X", -sp),
114.     "e": ("Y", sp),
115.     "a": ("Y", -sp),
116.     "s": ("Z", sp),
117.     "d": ("Z", -sp),
118. }
119.
120. def key_rotate(axis, t):
121.     rotation_speeds[axis] = t
122.
123. for k, (axis, t) in rotate.items():
124.     win.bind(f"<Key-{k}>", lambda event, axis=axis, t=t: key_rotate(axis, t))
125.
126. while True:
127.     C.delete('all')
128.
129.     rotated_coords = []
130.     for i in range(8):
131.         rotated_coords.append(rotate_x(coordinates[i], rotation_speeds["X"]))
132.         rotated_coords[i] = rotate_y(rotated_coords[i], rotation_speeds["Y"])
133.         rotated_coords[i] = rotate_z(rotated_coords[i], rotation_speeds["Z"])
134.
135.     plot()
136.     update_cube_coordinates()
137.
138.     at_wall = 0
139.     if Vx < -bd:
140.         xSpeed = abs(xSpeed)
141.         at_wall = 1
142.     elif Vx > ww + bd:
143.         xSpeed = -abs(xSpeed)
144.         at_wall = 1
145.     if Vy < -bd:
146.         ySpeed = abs(ySpeed)
147.         at_wall = 1
148.     elif Vy > hh + bd:
149.         ySpeed = -abs(ySpeed)
150.         at_wall = 1
151.     if Vz < 400:
152.         zSpeed = abs(zSpeed)
153.         at_wall = 1
154.     elif Vz > 1000:
155.         zSpeed = -abs(zSpeed)
156.         at_wall = 1
157.
158.     if at_wall:
159.         rotation()
160.
161.     Vx += xSpeed
162.     Vy += ySpeed
163.     Vz += zSpeed
164.
165.     win.update()
166.