Simuler le saut d'un personnage dans un champ de pesanteur - Application à un logo génératif

Par Damien MUTI et Chloé Berthon (BTS DG2, 2019-2020)

Il s'agit de donner les outils théoriques et pratiques permettant de simuler le saut d'un personnage représenté dans cet exemple par une balle, dans un champ de pesanteur (sur la Terre, la Lune ou autre...).

Objectif

Créer un logo génératif

Lors de son projet de synthèse de BTS en 2019-2020, Cloé Berthon a généré un logo génératif pour une association de trampoline nommée “Acrosphère”. Dans son logo, la lettre “O” doit sauter alternativement comme si elle rebondissait sur un trampoline.

Le Gif suivant illustre le principe :

La vidéo associé :

logo1.mp4

La présentation du projet est disponible sur les documents suivants :

presentation_projet_processing.pdf

planche_logo_generatif_cloe.pdf

Le code initial associé au projet est le suivant. Il présente une version “multiballe” fortement inspiré du tutoriel “Pong” :

logo_g_n_ratif_2.zip

Rendu graphique :

Dynamique du saut

On considère une balle représentant une lettre ou un personnage qui, à partir d'une position initiale, saute vers le haut, atteint une position haute à la vitesse nulle et subit une redescente vers sa position initiale.

Un peu de théorie

le modèle du saut est celui d'un objet soumis uniquement à la gravité g, c'est à dire le modèle de la chute libre. On considère uniquement un mouvement suivant y comme le montre la figure ci-dessus et ci-dessous:

// ___________► x
// |
// | o (v→)= = v(t).(uy→) avec v(t) algébrique
// | ↓ (P→) : poids
// ▼
// y

Dans le repère (o,x,y), la deuxième loi de newton donne appliqué au système {balle} donne :

Σ(F→) = m*(a→) =(P→) = m*(g→) <=> (a→)= (g→)

en projection sur l'axe (oy), on obtient : a = d²y/dt² = g (car ici le poids (P→) est colinéaire et de même sens que (uy→), avec g : gravité (sur Terre gT=9,81 m*s-², sur la Lune gL = 1,6 m*s-², etc...) soit :

* v(t) = g*t + V0 (1)
* y(t) = y0 + V0*t + (1/2)*g*t² (2)

avec y0 : le position de la balle à t=0 (début du saut) et V0 : vitesse initiale algébrique de la balle à t=0 (début du saut).

Hauteur de saut et ordonnée minimale atteinte

Approche dynamique

y(t) est minimal à l'instant tmin, lorsque la vitesse atteinte est nulle:

dy(t)/dt = v(t) = 0 <=> tmin = -V0/g

D'où:

ymin = y(tmin) = y0 - V0²/g + V0²/(2*g) = y0 - V0²/(2*g)

soit :

ymin = y0 - V0²/(2*g) (3)

La hauteur h (en valeur absolue) du saut est donc :

h = y0 - ymin = V0²/(2*g) (4)

approche énergétique

On retrouve le même résultat en appliquant le théorème de l'énergie mécanique au système {balle} en chute libre, dans le référentiel supposé galiléen. Ce théorème stipule que sans frottement, l'énergie du système se conserve :

EM = EC + EPP = Constante (5)

dans lequel EC est l'énergie cinétique du système de masse m, à un instant t:

EC = (1/2)*m*V²

et EPP est l'énergie potentielle de pesanteur dans le champs de gravité (g→), à un instant t :

EPP = m*g*h(t), avec h(t) = y0-y(t)

On applique le théorème de l'énergie mécanique à l'instant initial (t=0) pour lequel V=V0 et h=0, et à l'instant tmin au moment où la hauteur maximale h est atteinte :

EM(0) = (1/2)*m*V0²
EM(tmin) = m*g*h

L'énergie mécanique étant constante, on a EM(0) = EM(tmin), donc :

m*g*h = (1/2)*m*V0² <=> h = V0²/(2*g) (4)

En simplifiant par la masse m et et extrayant h, on retrouve le résultat (4) obtenu précédemment.

Discussion sur les unités

Ici, l'unité de temps est la durée entre deux frames consécutive. Ce temps est donc proportionnel au nombre “n” de frames qui s'est écoulé à partir de la frame considérée comme le début du saut. Pour simplifier le modèle on considère ici que t=n, avec n, le nombre d'itération de la boucle draw() à partir du début du saut (à t=0).

La position y qui est normalement en mètre (m), est ici en “pixel” (px) : m <-> px

Le temps t qui est normalement en seconde (s), est ici en “frame” : t <-> fr

La vitesse qui est normalement en mètre par seconde (m/s), est ici en pixels par “frame” : m/s <-> px/fr

L'accélération qui est normalement en m/s² est ici en pixels par frame au carré : m/s² <-> px/fr²

Discussion sur les paramètres influençant le rendu graphique : y0, V0 et g

Relations importantes

Pour résumer, les relations importantes qui influencent le rendu graphique sont les suivantes :

* v(t) = g*t + V0 (1)
* y(t) = y0 + V0*t + (1/2)*g*t² (2)
* ymin = y0 - V0²/(2*g) (3)
* h = y0 - ymin = V0²/(2*g) (4)
* tmin = -V0/g (facultatif)

On remarque donc que la position y(t) et la vitesse v(t) dépendent des conditions initiales (y0, V0) de la gravité g et du temps t.

la hauteur du saut ou l'ordonnée minimale atteinte dépendent quant à elle uniquement des conditions initiales (y0, V0) et de la gravité g.

Réglage des paramètres

Les paramètres qui influence le rendu graphique sont :

y0 : position initiale de la balle. Généralement fixé par l'utilisateur

V0 : Vitesse initiale de l’impulsion. une vitesse de déplacement de la balle supérieure à 10 pixels par frames peut provoquer un effet de discontinuité visuelle dans le mouvement. On pourra prendre par exemple V0 = 5px/fr.

g : gravité. Il sera nécessaire de bien choisir ce paramètre pour que le rendu graphique soit convenable. Il ne s'agit donc plus de la gravité terrestre, mais d'une planète exotique de très faible masse...

t : le temps du référentiel considéré. Ce paramètre aussi est différent du temps terrestre car dépend intrinsèquement de la vitesse de défilement des images (par défaut 30 frames par secondes sur Processing).

Un exemple : Dans l'exemple développée par Cloé Berthon lors de son projet de synthèse de BTS en 2019-2020, dans lequel est a généré un logo génératif pour une association de trampoline (voir en bas de page), les paramètres sont les suivants :

y0 = 250 px

V0 = 5 px/fr

h = 200 px (ou ymin = 50px)

La relation (4) précédente nous permet de calculer la valeur de g :

h = V0²/(2*g) <=> g = V0²/(2*h)
Application Numérique : g = 5²/(2*200) = 0,0625 px/fr²

Concrètement, il suffira de donner au programme la vitesse initiale V0 et la hauteur maximale h du saut et le programme se chargera de calculer la valeur de g grâce à la formule :

g = V0²/(2*h) (5)

Précaution sur la valeur des paramètres pour que la balle ne dépasse pas du cadre

Pour que le balle ne dépasse pas du cadre, il est nécessaire que y0 reste positif:

ymin>0 <=> y0 > V0²/(2*g)

la condition sur la vitesse initiale est donc que :

|V0| < √(2*g*y0)

Algorithme

Attributs liés au saut :

position initiale : y0 (en pixel)

vitesse initiale V0 (en pixels par frame)

temps lié au mouvement : t (en frames : ici t=n, avec n, le nombre d'itération de la boucle draw() à partir du début du saut (à t=0)

position de la balle à un instant t: y (en pixels).

variable booléenne permettant de savoir si la balle est en action de saut ou non : isJumping = true si la balle est en train de sauter, isJumping=false sinon.

Initialement, il faut s'assurer d'avoir bien réglé la vitesse initiale du saut en fonction de la position initiale y0 et de la taille de la fenêtre d'affichage (paramètre “height”).

Actions lié au saut :

Action détectée dans void keyPressed():

Débuter le saut : par exemple en appuyant sur une touche.

lancer le chronomètre: régler l'attribut t de la balle à 0 (t=0)

noter que la balle est en action de saut : régler l'attribut isJumping=true

faire évoluer le saut à chaque itération de la boucle draw() en appelant la méthode sauter() de la balle :

Si (isJumping=true) ET que y est inférieur ou égale à y0 (y<=y0):
- calculer la nouvelle position de la balle : y = y0 + V0*t + (1/2)*g*t²
- incrémenter le temps : t++
Sinon ((isJumping=false) OU y est strictement supérieur à y0 (y>y0)):
* replacer la balle à la position initiale y=y0
* réinitialiser le temps : t=0
* noter que la balle n'est plus en action de saut :
régler l'attribut isJumping=false

Le programme

Le code Processing du programme est le suivant : logo_g_n_ratif_6.zip

Dans ce programme, l'ensemble des frames correspondant à 3 rebonds de la lettre “O” sont enregistrées dans un dossier “video”.

Il est ensuite possible de créer une vidéo à partir des frames en allant dans : Outil > MovieMaker. Suivre ensuite le tutoriel donné par Daniel Shifmann : * Tuto sur comment faire une vidéo à partir d'un scketch de Daniel Shifmann

Références

Enregistrer une vidéo à partir d'une animation Processing :

sauvegarde d'images par saveFrames()

Tutoriels sur la librairie Video

Tuto sur comment faire une vidéo à partir d'un scketch de Daniel Shifmann

saveFrames()