Faire une animation en 3D avec Sage
18 janvier 2012 | Catégories: animation, sage | View CommentsEn Sage, il est relativement facile de créer des animations d'images en 2D. Pour cela, il suffit d'utiliser la commande animate qui s'occupera d'utiliser les commandes plus compliquées ffpmeg ou convert. Plusieurs exemples sont disponibles dans la documentation de Sage ou sur le wiki de Sage.
Par contre, il n'est pas encore possible de faire une animation d'objets graphiques 3D. Le logiciel Jmol, utilisé dans Sage pour faire de la visualisation 3D le permet, car les chimistes l'utilise pour faire des animations 3D de molécules complexes, mais cette fonctionalité n'a pas encore été exportée dans Sage. En juin dernier, j'en ai parlé à Jonathan Gutow, responsable des mises à jour de Jmol dans Sage, mais il doit d'abord régler d'autres problèmes plus importants.
En attendant, il est possible de s'en sortir en utilisant Tachyon plutôt que Jmol. Je rappelle que Tachyon est utilisé dans Sage pour créer des images png d'objets graphiques 3d. Ensuite, on peut immiter ce que la fonction animate fait pour créer une animation d'une scène 3d.
Pour illustrer la méthode par un exemple, faisons une animation de la technique des liens dansants de Knuth pour trouver les solutions du puzzle Quantumino.
Dans un répertoire, créer un fichier Sage video_quantumino.sage qui contiendra le code suivant:
from sage.games.quantumino import QuantuminoSolver import itertools def animate(block=4, stop=400, angle=pi/200.0, nb_pareil=5): r""" This functions creates plenty of png images in the images folder. INPUT: - ``block`` - integer between 0 and 16, the block to put aside - ``stop`` - integer, number of iterations - ``angle`` - number, rotation angle (radian) between each frame - ``nb_parei`` - integer, number of frame per iteration OUTPUT: Plenty of png images in the images folder. """ q = QuantuminoSolver(block) it = q.solve(partial='incremental') i = 0 for solution in itertools.islice(it, stop): G = solution.show3d() G += sphere((4,7,1),size=0.1,opacity=0) # hack to stabilize the frame G += sphere((0,7,0),size=0.1,opacity=0) # hack to stabilize the frame #G += sphere((2,4,1),size=10,opacity=0) # pas opaque pantoute for _ in range(nb_pareil): H = G.rotateZ(angle * i) filename = 'images/image%s.png' % i H.save(filename, frame=False, aspect_ratio=1) print "Création du fichier %s" % filename i += 1 animate(4, stop=20, angle=pi/200.0, nb_pareil=5)
Créer les images à l'aide de Sage >= 4.7.2
mkdir images sage video_quantumino.sage
Aller dans le répertoire images et faites ensuite:
cd images ffmpeg -y -f image2 -r 20 -i image%d.png video.mpg
Le résultat est ici (bloc numéro 4 mis de côté, 200 itérations, angle=\(\pi\)/200, 5 images par itérations, total de 1000 images):