VPython est l’extension de Python par le module visual qui permet l’affichage d’objets en 3D.
VPython est distribué sur http://vpython.org/ en versions Linux / Mac OS X / Windows pour Python 2.X et Python 3.X.
La documentation est disponible en ligne sur http://vpython.org/, mais elle se trouve aussi dans les dossiers d’installation de VPython, avec de nombreux exemples de programmes. (Sous linux faire par exemple locate vpython pour trouver les dossiers où est installé vpython. Souvent la documentation et les exemples résident dans /usr/share/doc/vpython-doc-....)
Warning
Cette extension est distribuée sous le nom de VPython mais le module à importer s’appelle visual. Dans la pratique, on parle indifféremment de module visual ou module VPython.
Premier pas ... un simple parallélépipède rectangle (en très gros plan):
import visual
# dessiner une boîte:
visual.box()
Souvent au lieu de faire import visual on fera: from visual import * ce qui évitera ensuite dans le programme de devoir préfixer les noms des fonctions du module par visual. On pourra alors écrire directement:
from visual import *
box()
sphere(pos=(10,10,3))
pour obtenir un boîte et une sphère. La boîte est en fait ici un cube centré à l’origine du repère et la sphère est centrée en (10,10,3), ces trois composantes étant respectivement la position horizontale, la position verticale, et la position selon la profondeur.
La librairie travaille en 3D. Toutefois, il est possible d’indiquer seulement 2 coordonnées pour un objet, dans ce cas la profondeur prend pour valeur 0.
La plupart des objets ont une propriété pos et une propriété color (i.e., position et couleur). D’autres propriétés sont utilisées selon le type d’objets, par exemple une boîte a aussi des propriétés donnant sa longueur, sa hauteur et sa largeur (selon l’axe profondeur):
box(pos=(0,-5,0), length=40, height=1, width=30, color=color.blue)
Les propriétés de taille et de position sont stockées en nombres flottants.
Warning
La fenêtre de visualisation s’adapte (en général) automatiquement pour que l’on puisse voir tous les objets de la scène. Il existe une option permettant de modifier ce comportement.
La fenêtre de visualisation fournit la possibilité de tourner et de zoomer dans la scène à l’aide de la souris, pendant l’exécution du programme:
Selon les raccourcis déjà associés à la souris, il peut aussi être nécessaire d’utiliser les touches “CTRL” ou “ALT” conjointement aux boutons de la souris.
Note
Les print, les input et les raw_input sont réalisés dans la fenêtre où l’interpréteur Python s’exécute et non dans la fenêtre graphique de visualisation VPython.
Lorsque les paramètres ne sont pas donnés, ils ont des valeurs par défaut. Pour les paramètres principaux ces valeurs sont:
Les objets créés peuvent être stockés dans des variables, pour pouvoir être ensuite modifiés de façon dynamique pendant l’exécution. Voici trois objets stockés dans les variables a, b et sol:
a = box(pos=(0,1,0))
b = sphere(pos=(10,10,3))
sol = box(pos=(0,0,0), length=40, height=1, width=30, color=color.green)
Pour modifier la position d’un objet:
b.x=2
b.y=1
b.z=20
ou encore:
b.pos=(2,1,20)
Il est aussi possible de modifier dynamiquement les autres propriétés (radius, color, length ...):
b.color = color.red
b.radius = 4
Par défaut, après sa création un objet est visible, mais il est possible de le cacher:
b.visible = False
et de le montrer de nouveau:
b.visible = True
Les propriétés peuvent être consultées avec la même notation. Par exemple, on pourra utiliser le rayon de la sphère b pour créer une sphère de rayon deux fois plus grand:
c = sphere(radius = b.radius*2)
ou encore incrémenter l’abscisse du centre de la sphère pour la translater selon l’axe des x:
b.x = b.x + 4
Warning
Lors d’une affectations, en fait ce n’est pas l’objet graphique lui-même qui est stocké dans la variable, mais son identifiant (comme pour les listes). Ainsi b = sphere(pos=(10,10,3), radius=5) crée un objet dont l’identifiant est stocké dans b. Si l’on exécute:
b = sphere(pos=(10,10,3), radius=5)
e = b
e.radius = 10
dans ce cas l’identifiant d’objet contenu dans b est recopié dans e, il n’y a pas création d’une seconde sphère, nous avons une seule et unique sphère. L’instruction e.radius = 10 modifie le rayon de la sphère dont l’identifiant est dans e, cette instruction a donc le même effet que b.radius = 10
Note
La bibliothèque VPython fournit un objet curve, qui permet de tracer des graphes de fonctions en 2D/3D, sous forme explicite et sous forme paramétrique.
Note
Pour essayer les composants graphiques, il est tout à fait possible de faire des tests depuis l’interpréteur interactif Python après avoir importé le module visual.
Pour faire des animations, il suffit de modifier les propriétés des objets par programme dans une boucle. Voici un exemple d’animation:
from visual import *
from math import *
from random import *
terre = sphere(pos=(0,0,0), radius=14, color=color.blue)
lune = sphere()
vaisseau = sphere(pos=(0,30,0), radius=0.5, color=color.red)
angle = 0.0
distance = 40.0
while True:
lune.x = distance * cos(angle)
lune.y = distance * sin(angle)
vaisseau.x = vaisseau.x + random() - 0.5
vaisseau.y = vaisseau.y + random() - 0.5
angle = angle + pi/1000
rate(100)
Note
La fonction rate du module VPython permet de garantir un temps d’attente minimal (rate(n) impose une attente d’au moins 1/n seconde). Elle est utilisée ici pour ralentir l’animation.
Note
Il est possible d’arrêter le programme en appuyant sur la touche “ESCAPE”, VPython détecte cet événement et interrompt l’exécution.
Le module fournit un type vector pour créer et manipuler des vecteurs. La création d’un vecteur se note:
v = vector(2,4,3)
Note
Les composantes de ces vecteurs sont toujours des flottants, même si elles sont données sous la forme d’entiers (dans ce cas elles sont converties et stockées en flottant).
Un vecteur peut être utilisé pour fixer la position d’un objet (en fait la propriété pos est du type vector):
b.pos = vector(2,4,3)
a.pos = v
Le module fournit divers opérations sur les vecteurs. Telles que l’addition, la soustraction et la multiplication par un scalaire:
v1 = vector(2,3,0)
v2 = 3 * v + v1 - vector(0,0,5)
ou encore la norme (appelée magnitude):
normeV = mag(v)
Il est aussi possible par une simple affectation de modifier la norme d’un vecteur, ce vecteur gardant la même direction et le même sens:
v1.mag=2
Warning
La fonction norm existe mais ne fournit pas la norme, elle permet d’obtenir le vecteur normalisé correspondant (vecteur de même direction et de même sens, mais de norme 1):
w = norm(v) # c'est n'est pas la norme de v !
Le type vector permet d’exprimer les calculs de façon plus naturelle et compacte. Ainsi dans l’exemple précèdent on pourra remplacer:
vaisseau.x = vaisseau.x + random() - 0.5
vaisseau.y = vaisseau.y + random() - 0.5
par:
vaisseau.pos = vaisseau.pos + vector(random()-0.5,random()-0.5,0)
On dispose aussi bien sûr du produit vectoriel:
cross(v1,v2)
et du produit scalaire:
k = dot(v1,v2)
En VPython les angles sont en radians (comme en Python). La constante pi est définie par VPython ainsi que les fonctions de conversion degrés <-> radians: degrees(x) et radians(x).
L’angle entre deux vecteurs peut s’obtenir avec la fonction diff_angle:
v1 = vector(3,1,2); v2 = vector(1,-3,6)
a = v1.diff_angle(v2)
Pour les rotations, la fonction rotate fournit le vecteur résultant de la rotation d’un autre vecteur:
v1 = vector(2,3,1)
v3 = rotate(v1, angle=0.1, axis=(0,1,1))
où angle est l’angle de rotation et axis est un vecteur qui donne l’axe de rotation.
Les rotations peuvent directement être appliquées sur les objets graphiques:
b = box()
b.rotate(angle=0.1, axis=(2,3,0), origin=(10,0,0))
Dans cet exemple, l’objet dont l’identifiant est dans b, est transformé par une rotation de 0.1 radian autour de l’axe orienté selon le vecteur (2,3,0) et passant par le point (10,0,0).
Si axis et origin ne sont pas spécifiés, c’est l’axe principal et l’origine de l’objet (en général le centre de l’objet) qui sont utilisés. Essayer par exemple:
b=box()
for i in range(400):
rate(100)
b.rotate(angle=0.01)