Advertisement
here2share

# tk_3d_voxel_animation.py

Sep 10th, 2024
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.80 KB | None | 0 0
  1. # tk_3d_voxel_animation.py
  2.  
  3. import tkinter as tk
  4. import math
  5.  
  6. def create_cube():
  7.     voxels = []
  8.     for x in range(-1, 2):
  9.         for y in range(-1, 2):
  10.             for z in range(-1, 2):
  11.                 voxels.append((x, y, z))
  12.     return voxels
  13.  
  14. def rotate_point(x, y, z):
  15.     x0 = math.radians(angle_x + move_x)
  16.     y0 = math.radians(angle_y + move_y)
  17.     z0 = math.radians(angle_z + move_z)
  18.  
  19.     # Rotate around Z-axis
  20.     new_x = x * math.cos(z0) - y * math.sin(z0)
  21.     new_y = x * math.sin(z0) + y * math.cos(z0)
  22.  
  23.     # Rotate around Y-axis
  24.     new_x, new_z = new_x * math.cos(y0) - z * math.sin(y0), new_x * math.sin(y0) + z * math.cos(y0)
  25.  
  26.     # Rotate around X-axis
  27.     new_y, new_z = new_y * math.cos(x0) - new_z * math.sin(x0), new_y * math.sin(x0) + new_z * math.cos(x0)
  28.  
  29.     return new_x, new_y, new_z
  30.  
  31. def project(x, y, z):
  32.     factor = 200 / (4 - z)
  33.     return cx + x * factor, cy - y * factor
  34.  
  35. def draw_voxel(x, y, z):
  36.     size = 20 / (4 - z)
  37.     x0, y0 = project(x, y, z)
  38.     canvas.create_rectangle(x0-size, y0-size, x0+size, y0+size, fill="white", outline="")
  39.  
  40. def draw_grid_line(angle):
  41.     rad = math.radians(angle)
  42.     x_offset = 300 * math.cos(rad)
  43.     y_offset = 300 * math.sin(rad)
  44.     canvas.create_line(cx, cy, cx + x_offset, cy - y_offset, fill="red")
  45.  
  46. def update_status():
  47.     status_var.set(f"@ Angle: {angle % 360:.2f}°, Cube Rotation Angles -> Angle X: {move_x % 360:.2f}°, Angle Y: {move_y % 360:.2f}°, Angle Z: {move_z % 360:.2f}°")
  48.  
  49. def on_x_slider_cube(value):
  50.     global angle_x
  51.     angle_x = float(value)
  52.  
  53. def on_y_slider_cube(value):
  54.     global angle_y
  55.     angle_y = float(value)
  56.  
  57. def on_z_slider_cube(value):
  58.     global angle_z
  59.     angle_z = float(value)
  60.  
  61. def on_x_slider_move(value):
  62.     global move_x0
  63.     move_x0 = float(value)
  64.  
  65. def on_y_slider_move(value):
  66.     global move_y0
  67.     move_y0 = float(value)
  68.  
  69. def on_z_slider_move(value):
  70.     global move_z0
  71.     move_z0 = float(value)
  72.  
  73. def rotate_voxel_cube():
  74.     global move_x, move_y, move_z
  75.     move_x += (move_x0) % 360
  76.     move_y += (move_y0) % 360
  77.     move_z += (move_z0) % 360
  78.  
  79. def print_current_angles():
  80.     print(status_var.get())
  81.  
  82. def reset():
  83.     global angle_x, angle_y, angle_z, move_x, move_y, move_z, move_x0, move_y0, move_z0, angle
  84.     angle_x = 0
  85.     angle_y = 0
  86.     angle_z = 0
  87.     move_x, move_y, move_z = 0, 0, 0
  88.     move_x0, move_y0, move_z0 = 0, 0, 0
  89.     angle = 0
  90.  
  91.     x_slider_move.set(0)
  92.     y_slider_move.set(0)
  93.     z_slider_move.set(0)
  94.     x_slider.set(0)
  95.     y_slider.set(0)
  96.     z_slider.set(0)
  97.  
  98. def reset_move():
  99.     global angle_x, angle_y, angle_z, move_x, move_y, move_z, move_x0, move_y0, move_z0, angle
  100.     move_x, move_y, move_z = 0, 0, 0
  101.     move_x0, move_y0, move_z0 = 0, 0, 0
  102.  
  103.     x_slider_move.set(0)
  104.     y_slider_move.set(0)
  105.     z_slider_move.set(0)
  106.  
  107. def f_angle():
  108.     global angle
  109.     angle = (angle - 30) % 360
  110.  
  111. def b_angle():
  112.     global angle
  113.     angle = (angle + 30) % 360
  114.  
  115. ww = 600
  116. hh = 600
  117. cx = 600 // 2
  118. cy = 600 // 2
  119.  
  120. root = tk.Tk()
  121. root.title("3D Voxel Animation")
  122. root.geometry(f"{1200}x{hh}+0+0")
  123.  
  124. canvas = tk.Canvas(root, width=ww, height=hh, bg="black")
  125. canvas.pack(side=tk.RIGHT)
  126.  
  127. control_frame = tk.Frame(root)
  128. control_frame.pack(side=tk.LEFT, fill=tk.Y)
  129.  
  130. # Status Display
  131. status_var = tk.StringVar()
  132. status_label = tk.Label(control_frame, textvariable=status_var)
  133. status_label.pack()
  134.  
  135. # Button Frame
  136. button_frame = tk.Frame(control_frame)
  137. button_frame.pack(side=tk.BOTTOM, fill=tk.X)
  138.  
  139. speed = 1
  140. x_slider_move = tk.Scale(control_frame, from_=-speed, to=speed, orient=tk.VERTICAL, label="X", resolution=0.005)
  141. x_slider_move.pack(side=tk.LEFT, fill=tk.Y)
  142.  
  143. y_slider_move = tk.Scale(control_frame, from_=-speed, to=speed, orient=tk.VERTICAL, label="Y", resolution=0.005)
  144. y_slider_move.pack(side=tk.LEFT, fill=tk.Y)
  145.  
  146. z_slider_move = tk.Scale(control_frame, from_=-speed, to=speed, orient=tk.VERTICAL, label="Z", resolution=0.005)
  147. z_slider_move.pack(side=tk.LEFT, fill=tk.Y)
  148.  
  149. x_slider_move.bind("<Motion>", lambda e: on_x_slider_move(x_slider_move.get()))
  150. y_slider_move.bind("<Motion>", lambda e: on_y_slider_move(y_slider_move.get()))
  151. z_slider_move.bind("<Motion>", lambda e: on_z_slider_move(z_slider_move.get()))
  152.  
  153. # Cube Position Sliders
  154. x_slider = tk.Scale(control_frame, from_=0, to=360, orient=tk.VERTICAL, label="Cube X", resolution=5)
  155. x_slider.pack(side=tk.LEFT, fill=tk.Y)
  156.  
  157. y_slider = tk.Scale(control_frame, from_=0, to=360, orient=tk.VERTICAL, label="Cube Y", resolution=5)
  158. y_slider.pack(side=tk.LEFT, fill=tk.Y)
  159.  
  160. z_slider = tk.Scale(control_frame, from_=0, to=360, orient=tk.VERTICAL, label="Cube Z", resolution=5)
  161. z_slider.pack(side=tk.LEFT, fill=tk.Y)
  162.  
  163. x_slider.bind("<Motion>", lambda e: on_x_slider_cube(x_slider.get()))
  164. y_slider.bind("<Motion>", lambda e: on_y_slider_cube(y_slider.get()))
  165. z_slider.bind("<Motion>", lambda e: on_z_slider_cube(z_slider.get()))
  166.  
  167. angle_y_button = tk.Button(button_frame, text="Rotate Voxel Cube", command=lambda: rotate_voxel_cube())
  168. angle_y_button.pack(side=tk.LEFT)
  169.  
  170. print_button = tk.Button(button_frame, text="Print Data", command=print_current_angles)
  171. print_button.pack(side=tk.LEFT)
  172.  
  173. f_angle_button = tk.Button(button_frame, text="+30 Degrees", command=f_angle)
  174. f_angle_button.pack(side=tk.LEFT)
  175.  
  176. b_angle_button = tk.Button(button_frame, text="-30 Degrees", command=b_angle)
  177. b_angle_button.pack(side=tk.LEFT)
  178.  
  179. reset_button = tk.Button(button_frame, text="RESET ALL", command=reset)
  180. reset_button.pack(side=tk.LEFT)
  181.  
  182. reset_button = tk.Button(button_frame, text="RESET MOVE", command=reset_move)
  183. reset_button.pack(side=tk.LEFT)
  184.  
  185. reset()
  186. voxels = create_cube()
  187.  
  188. while True:
  189.     canvas.delete("all")
  190.     rotate_voxel_cube()
  191.     draw_grid_line(angle)
  192.     for voxel in voxels:
  193.         x, y, z = rotate_point(*voxel)
  194.         draw_voxel(x, y, z)
  195.  
  196.     update_status()
  197.     canvas.update()
  198.  
  199. root.mainloop()
  200.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement