Files
INF6B/cube/main.py
rattatwinko d0eaabdd87 some new stuff.
idk its all pretty fun! some C++ too!
2025-10-15 11:16:51 +02:00

143 lines
3.2 KiB
Python

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
from matplotlib.widgets import Button
cube_points = np.array([
[-1, -1, -1],
[-1, -1, 1],
[-1, 1, -1],
[-1, 1, 1],
[ 1, -1, -1],
[ 1, -1, 1],
[ 1, 1, -1],
[ 1, 1, 1]
])
edges = [
(0, 1), (0, 2), (0, 4),
(1, 3), (1, 5),
(2, 3), (2, 6),
(3, 7),
(4, 5), (4, 6),
(5, 7),
(6, 7)
]
def rotation_y(theta):
return np.array([
[np.cos(theta), 0, np.sin(theta)],
[0, 1, 0], # 0,1,0
[-np.sin(theta), 0, np.cos(theta)]
])
def rotation_z(theta):
return np.array([
[np.cos(theta), -np.sin(theta), 0],
[np.sin(theta), np.cos(theta), 0],
[0, 0, 1]
])
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_zlim(-2, 2)
ax.set_box_aspect([1, 1, 1])
ax.set_title("Matrixmultiplikation", pad=20)
lines = [ax.plot([], [], [], color='red')[0] for _ in edges]
text = ax.text2D(1.02, 0.5, "", transform=ax.transAxes,
fontsize=10, color='black', family='monospace', va='center')
paused = False
highlight = False
points_scat = None
labels = []
def update(frame):
global points_scat, labels
if paused:
return lines + [text]
theta = np.radians(frame)
R_y = rotation_y(theta)
R_z = rotation_z(theta * 0.7)
R = R_y @ R_z
rotated = cube_points @ R.T
# Update edges
for line, (i1, i2) in zip(lines, edges):
p1, p2 = rotated[i1], rotated[i2]
line.set_data([p1[0], p2[0]], [p1[1], p2[1]])
line.set_3d_properties([p1[2], p2[2]])
# Update rotation matrices display
matrix_str_y = "\n".join(
["[" + " ".join(f"{val:+.2f}" for val in row) + "]" for row in R_y]
)
matrix_str_z = "\n".join(
["[" + " ".join(f"{val:+.2f}" for val in row) + "]" for row in R_z]
)
matrix_str_R = "\n".join(
["[" + " ".join(f"{val:+.2f}" for val in row) + "]" for row in R]
)
text.set_text(
f"θ = {np.degrees(theta):6.2f}°\n"
f"sin(θ) = {np.sin(theta): .3f}\n"
f"cos(θ) = {np.cos(theta): .3f}\n\n"
f"R_y(θ):\n{matrix_str_y}\n\n"
f"R_z(0.7θ):\n{matrix_str_z}\n\n"
f"R = R_y · R_z:\n{matrix_str_R}"
)
# Always show vertex points and labels
if points_scat is None:
points_scat = ax.scatter([], [], [], color='blue', s=40)
points_scat._offsets3d = (
rotated[:, 0], rotated[:, 1], rotated[:, 2]
)
for label in labels:
label.remove()
labels.clear()
for i, p in enumerate(rotated):
labels.append(ax.text(p[0], p[1], p[2], f"P{i}",
color='black', fontsize=8))
return lines + [text]
axpause = plt.axes([0.4, 0.02, 0.3, 0.05])
bpause = Button(axpause, 'Pause / Resume')
def toggle_pause(event):
global paused
paused = not paused
def toggle_highlight(event):
global highlight
highlight = not highlight
bpause.on_clicked(toggle_pause)
ani = FuncAnimation(
fig, update, frames=np.arange(0, 360, 2),
interval=50, blit=False
)
plt.show()