Table des matières
Bille qui rebondit
Lorsque l'on fait des animations, on doit souvent prévoir des comportement qui semblent physiquement acceptables :
- un objet qui rebondit,
- un objet qui s'écrase sous son poids,
- un ressort qui se tend et se détend,
- des objets qui se percutent…
Nous allons suivre ici l'exemple d'une bille qui rebondit.
Dans un premier temps, nous n'utiliserons pas de classe. Dans un deuxième temps nous ajouterons une classe pour permettre l'étape suivante : beaucoup de billes qui rebondissent.
Physique de base
Notre bille sera un cercle d'un certain diamètre taille d, une certaine position x, y. À chaque instant la bille tombera verticalement avec une vitesse vy. L'accélération de la pesanteur g modifiera la valeur de vy. Enfin, la bille rebondira sur la ligne du bas de la fenêtre mais en perdant un peu de vitesse. On notera r le facteur de proportionnalité entre la vitesse avant le choc et la vitesse après le choc. On a bien sûr 0 < r <= 1.
ygrandit vers le bas. Le sol est atteint quand on touche le bord inférieur de la fenêtre. On peut connaître la hauteur de la fenêtre grâce au mot-cléheight. Idem pour la largeur avecwidth.- on ne choisit pas pour
gla valeur physique de $9,81\,m\cdot s^{-2}$ car il faudrait alors faire une conversion prenant en compte l'unité de longueur sur l'écran et l'unité de temps de l'animation. Même si on mène ces calculs à bien, il n'est pas évident que l'animation en soit plus satisfaisante. Il est bien plus efficace de choisir, après quelques essais, la valeur qui produit l'animation la plus esthétique.
Si y > height, cela signifie que la bille a dépassé le bord du bas et qu'elle doit donc rebondir.
- le trajet qu'a fait la bille hors cadre est
depassement = y - height. Ce parcours aurait dû être fait dans l'autre sens, vers le haut. Donc on peut calculery = height - depassement. On peut tenir compte de la perte d'énergie et doncy = height - r*depassement. - la vitesse
vyest renversée mais avec une atténuation :vy = -r*vy.
Le script
final float g = 0.05;
final float r = 0.8;
int d; // diamètre bille
float x, y, vy;
void setup() {
size(600, 400);
x = 300;
y = 10;
vy = 0;
d = 5;
}
void draw() {
background(250); // en niveau de gris
vy += g;
y += vy;
if (y > height) {
// rebond
float depassement = y - height;
y = height - r*depassement;
vy = -r*vy;
}
circle(x, y, d);
}
Avec un objet
On peut confier la physique à la bille elle-même ce qui permettra de multiplier les billes sans alourdir le code.
final float g = 0.05;
final float r = 0.8;
Bille b;
void setup() {
size(600, 400);
b = new Bille(300, 10, 5);
}
void draw() {
background(250); // en niveau de gris
b.update();
b.display();
}
class Bille {
float x, y, vy, d;
Bille(float x0, float y0, float d0) {
d = d0;
x = x0;
y = y0;
vy = 0;
}
void update() {
vy += g;
y += vy;
if (y > height) {
// rebond
float depassement = y - height;
y = height - r*depassement;
vy = -r*vy;
}
}
void display() {
circle(x, y, d);
}
}
