Animazione HTML5+Javascript di un ipercubo >>> ipercubo.html
Animazione Python+Tkinter di un ipercubo >>> ipercubo.py
import tkinter as tk
from math import sin, cos
class Ipercubo:
def __init__(self, master):
self.master = master
self.canvas = tk.Canvas(master, width=600, height=600, bg='white')
self.canvas.pack()
self.angolo = 0.0
self.punti = self.genera_vertici()
self.spigoli = self.genera_spigoli()
self.disegna()
self.anima()
def genera_vertici(self):
# Vertici di un ipercubo in 4D
return [(-1, -1, -1, -1), (-1, -1, -1, 1), (-1, -1, 1, -1), (-1, -1, 1, 1),
(-1, 1, -1, -1), (-1, 1, -1, 1), (-1, 1, 1, -1), (-1, 1, 1, 1),
(1, -1, -1, -1), (1, -1, -1, 1), (1, -1, 1, -1), (1, -1, 1, 1),
(1, 1, -1, -1), (1, 1, -1, 1), (1, 1, 1, -1), (1, 1, 1, 1)]
def genera_spigoli(self):
# Genera gli spigoli tra i vertici
spigoli = []
for i in range(16):
for j in range(i + 1, 16):
if bin(i ^ j).count('1') == 1: # Collega i punti che differiscono in un solo bit
spigoli.append((i, j))
return spigoli
def proietta(self, punto):
# Proietta il punto 4D in 2D
z = punto[2]
k = 300 / (3 + z) # Fattore di prospettiva
x = punto[0] * k
y = punto[1] * k
return (x + 300, y + 300) # Trasla al centro del canvas
def disegna(self):
self.canvas.delete("all") # Pulisce il canvas
punti_proiettati = [self.proietta(self.ruota(punto)) for punto in self.punti]
# Disegna gli spigoli tra i vertici
for spigolo in self.spigoli:
self.canvas.create_line(punti_proiettati[spigolo[0]], punti_proiettati[spigolo[1]], fill='black')
def ruota(self, punto):
x = punto[0]
y = punto[1]
z = punto[2]
t = punto[3]
# Ruota l'ipercubo attorno agli assi
angolo_x = self.angolo * 0.1
angolo_y = self.angolo * 0.2
angolo_z = self.angolo * 0.3
angolo_t = self.angolo * 0.4
x, y = x * cos(angolo_x) - y * sin(angolo_x), x * sin(angolo_x) + y * cos(angolo_x)
y, z = y * cos(angolo_y) - z * sin(angolo_y), y * sin(angolo_y) + z * cos(angolo_y)
z, t = z * cos(angolo_z) - t * sin(angolo_z), z * sin(angolo_z) + t * cos(angolo_z)
t, x = t * cos(angolo_t) - x * sin(angolo_t), t * sin(angolo_t) + x * cos(angolo_t)
return (x, y, z, t)
def anima(self):
self.angolo += 0.05 # Incrementa l'angolo
self.disegna()
self.master.after(50, self.anima) # Richiama nuovamente anima dopo 50 ms
if __name__ == "__main__":
root = tk.Tk()
root.title("Ipercubo")
Ipercubo(root)
root.mainloop()
Per provare la versione Python è necessario disporre di un ambiente di sviluppo per Python, come Thonny – Python IDE for beginners scaricabile gratuitamente all’indirizzo https://thonny.org/
Dopo l’installazione di Thonny è sufficiente copiare e incollare il listato precedente nell’ambiente di sviluppo ed eseguirlo con il Run ▶.