|
|
Tutoriaux After Effects Le langage des expressions par
nab
Fonctions trigonométriques : cosinus, sinus
Cette partie risque de rappeler de mauvais souvenirs d'école à certains d'entre nous, mais le jeu en vaut la chandelle
car les applications sont nombreuses et variées.
Commençons par nous rafraîchir la mémoire en se rappelant les règles de base de trigonométrie ("l'art de mesurer les angles", éthymologiquement). La figure de gauche représente
les relations dans un triangle rectangle entre un angle et la longueur des côtés. Celle de droite représente ces relations sur un cercle, le cosinus se lit sur l'axe horizontal, le sinus sur l'axe vertical.

Nous avons vu précédemment qu'un vecteur était définit par ses composantes et qu'on le représentait par un tableau de nombres.
Ceci était l'aspect informatique du vecteur. Nous pouvons également voir le vecteur sous un aspect géométrique.
Considérons que nous sommes en 2D (c'est identique pour la 3D), choisissons un point au hasard, disons le point de coordonnées [140,120]. Ce point définit un vecteur géométrique ayant pour origine l'origine du repère
(le coin haut gauche de la composition) et pour extrémité le point lui-même. Il définit par conséquent deux triangles rectangles (en utilisant les axes du repère), et donc les formules précédentes entrent en jeu.

Nous aurons besoin de ces relations lorsque nous devrons calculer l'angle d'un vecteur par rapport à un axe ou à un autre vecteur par exemple, ou parfois pour mesurer la longueur d'un vecteur.
Animer un personnage par exemple (dont chaque membre est représenté par un calque), nous demandera des calculs de trigonométrie pour l'articulation des membres. Faire tomber une série de dominos nécessitera également ce type de calcul.
Les situations peuvent être variées, il y a souvent des problèmes géométriques à résoudre dans une animation.
Mais ce qui va nous servir le plus pour le moment ce sont les propriétés analytiques des fonctions trigonométriques.
Pour visualiser le comportement graphique de ces fonctions, créons un calque d'effets (dans une composition 25i/s, disons d'une durée de 10s) et ajoutons lui un paramètre glissière
(dans le menu "Effet", choisir "Options pour expressions" et "Paramètre glissière"). Le langage des expressions étant basé sur
le Javascript, les fonctions cos(), sin() et tan() sont notées Math.cos(), Math.sin(), Math.tan(). Appliquons à notre paramètre glissière (à son "Curseur") l'expression suivante:
Math.cos( time ) ;
Cliquons sur l'icône de courbe puis ajustons l'échelle du repère entre "-1" "+1", notre fenêtre de montage ressemble à cela:

Remarquons que toutes les valeurs fournies par la fonction cosinus sont comprises entre "-1" et "+1", cette particularité est valable aussi pour la fonction sinus. C'est une propriété forte qui peut nous être utile dans bien des situations.
En observant plus en détail la valeur du "Curseur", on voit qu'elle est de 1 à "time=0s" et à "time=6s+7images". Expliquons d'où vient ce "6s+7images". D'abord convertissons cela en secondes: nous sommes dans une composition à 25i/s,
donc une image dure exactement 1/25 secondes, soit 0.04s. "6s+7images" correspond donc à 6.28s. Tiens, ce chiffre nous dit-il quelque chose ? Non ? Alors divisons le par deux
et nous obtenons 3.14. Là, cela doit nous dire quelque chose: le fameux "Pi". Ce fameux "Pi" qui sera au passage noté "Math.PI" dans le langage des expressions (ceci provient également du Javascript).
Tous les "2*Pi" (comprendre ici toutes les 6.28 secondes), la fonction cosinus se répète. On dit qu'elle est de période 2*Pi. La période indique donc la durée entre deux "pics" (ou entre deux "creux").
L'inverse de la période est appelée la fréquence. Dans notre exemple la fréquence est donc de "1/(2*Pi)".
Ajustons la durée de notre composition en faisant en sorte de n'avoir qu'une seule période (nous choisirons une composition de 6s+8images pour que la dernière image sur la fenêtre de montage se situe à 6s+7images).
Intéressons nous maintenant à ce qui se passe lorsque l'on ajoute un coefficient multiplicateur devant "time", disons "3". Nous observons la courbe suivante:

Il y a maintenant trois fois plus de pics. La période s'est réduite d'un tiers, nous avons donc multiplié la fréquence du cosinus par "3".
Le coefficient que l'on vient d'ajouter correspond donc à la fréquence du cosinus. Plus on choisira un nombre élévé pour la fréquence, plus le nombre d'oscillations augmentera.
La variation se situe toujours par contre entre "-1" et "+1".
Enlevons notre coefficient "3" et ajoutons un nouveau coefficient multiplicateur mais cette fois mettons le devant l'expression, disons d'une valeur de "10". Nous observons cela:

Nous constatons cette fois-ci que le nombre d'oscillations n'a pas changé, en revanche les valeurs sont comprises maintenant entre "-10" et "+10". On appelle le coefficient que l'on vient de rajouter l'amplitude du cosinus. Plus ce nombre sera grand, plus la distance entre un "pic" et un "creux" va augmenter.
On jouera donc autour des paramètres de fréquence et d'amplitude pour contrôler notre cosinus.
Passons maintenant à un peu de pratique. Supposons que l'on veuille tracer cette jolie courbe cosinus à l'écran. Nous voudrions que le tracé soit centré par rapport au milieu de la composition
et que le tracé soit achevé exactement à la fin de la durée de notre composition.
Dans une composition de taille 160*120 et de durée 6s+8images, nous créons un calque solide et lui appliquons l'effet "Tracé dynamique". On ajoute maintenant l'expression suivante dans la propriété de position du "Tracé dynamique":
ampl = 50 ;
freq = 2 ;
vit = thisComp.width / thisComp.duration ;
horiz = [ 0 , thisComp.height / 2 ] ;
horiz + [ vit * time , ampl * Math.cos( freq * time ) ] ;
Expliquons cette expression pas à pas. Nous avons cinq instructions, toutes étant des affectations (variable à gauche, "=", valeur à droite).
La denière étant, comme nous l'avons vu, automatiquement considérée comme une affectation par After Effects, elle ne nécessite pas le "=". Le résultat de cette ligne sera la valeur affectée à la position du "Tracé dynamique".
Les deux premières instructions définissent l'amplitude et la fréquence de notre cosinus. Un choix trop grand pour l'amplitude ferait sortir le "crayon" de l'écran.
La troisième définit la vitesse (horizontale) de notre "Tracé". Comme on l'a appris à l'école, la vitesse s'exprime comme le rapport distance/temps. Dans notre exemple, nous souhaitons que le "Tracé" parcourt
toute la largeur de l'écran (notée "thisComp.width" dans le langage des expressions) pendant la durée de la composition (notée "thisComp.duration" dans le langage des expressions). On utilise la relation "vitesse=distance/temps".
La quatrième instruction définit le point qui se situe sur le bord gauche de la composition et au milieu ("thisComp.height" désignant la hauteur de notre composition).
Et enfin la dernière, elle porte en elle le résultat qui sera affecté à la position du "crayon". Commençons par la première composante du vecteur : elle va croître proportionnellement au temps qui s'écoule,
lorsque ce temps sera celui de la durée de la composition, alors cette composante sera égale à la largeur de la composition. Cela tombe bien c'est exactement ce que nous voulions, un "Tracé" qui s'achève à l'extrême gauche à la fin de la durée de la composition.
L'ajout du vecteur "horiz" nous permet d'avoir des oscillations autour de l'axe horizontal.
Remarquons que nous aurions également pu mettre des points clés pour animer le "Tracé" horizontalement, ce qui aurait éviter la variable de vitesse "vit". Notre fenêtre de montage aurait alors ressemblé à cela:

Une première clé de position pour le départ (au milieu à gauche), une seconde à l'arrivée (au milieu à droite), que nous plaçons sur la propriété de position du "Tracé"; ensuite dans l'expression on récupère la valeur de ce déplacement (horizontal)
en la stockant dans la variable "horiz". L'instruction est celle-ci:
horiz = effect ( " Tracé dynamique " ) ( " Position " ) ;
"horiz" va donc être un vecteur de dimension 2 représentant les valeurs de la position du "Tracé".
Si nous n'avions mis que le terme "position" en pensant faire référence à la position du "Tracé", nous aurions fait erreur car nous aurions fait référence la position du calque.
Notons également la manière de faire appel à la propriété d'un effet. On utilise le terme "effect" suivi du mon de l'effet et de la propriété
que l'on souhaite atteindre.
Au passage, rappelons nous qu'il est possible d'écrire "sans effort" une expression en utilisant l'escargot. Par exemple ici, dans cette dernière instruction, nous n'avons qu'à écrire "horiz=", ensuite on sélectionne
l'escargot et on le pointe vers la propriété de position du "Tracé". Le reste de la ligne "effect(..." vient s'afficher automatiquement.
Pensons toutefois à rajouter un ";" en fin d'instruction.
Nous pouvons aussi atteindre la propriété d'un effet en précisant son rang parmi toutes les propriétés que possède l'effet en question (ce rang commence à 1).
Dans notre exemple nous pouvons écrire " (1) " plutôt que d'écrire " ("Position") ", puisque la propriété "Position" est la première propriété
du "Tracé dynamique".

L'animation que nous obtenons en prévisualisant est celle-ci:
Si nous souhaitons maintenant que le "Tracé" ne commence pas par le bas mais par le haut de la composition.
Nous écrirons alors pour la dernière instruction :
depart + [ vit * time , - ampl * Math.cos( freq * time ) ] ;
en mettant un " - " devant notre cosinus, nous avons le "Tracé" suivant:
Profitons de l'occasion pour introduire quelque chose qui nous servira lorsque l'on écrira des expressions contenant plusieurs lignes d'instructions avec plusieurs paramètres.
Nous avons la possibilité de rajouter des commentaires dans nos expressions, ceci en vue d'une meilleure lecture et d'une compréhension plus rapide quand, dans deux mois par exemple,
nous réouvrirons ce projet. On pourrait par conséquent réécrire notre expression de cette manière :
ampl = 50 ; // amplitude en pixel
freq = 2 ; // fréquence
vit = thisComp.width / thisComp.duration ; // vitesse en pixel par seconde
horiz = [ 0 , thisComp.height / 2 ] ; // pour centrer
horiz + [ vit * time , ampl * Math.cos( freq * time ) ] ;
Certes ces commentaires ne nous serviront pas toujours, néanmoins c'est plutôt une bonne habitude à prendre car lorsque nous serons
amenés à écrire des expressions qui dépendront de beaucoup de paramètres, nous nous resituerons plus rapidement.
Nous n'allons pas voir autant en détail la fonction sinus, qui est en fait très similaire. Il s'agit de la même fonction
que la fonction cosinus mais décalée dans le temps. Regardons l'aspect de sa courbe avec la même méthode que précédemment.

On constate que maintenant la valeur du paramètre est de 1 lorsque "time" est entre "1s+14images" et "1s+15images".
Convertisssons en secondes, nous obtenons entre 1.56s et 1.60s.
Ceci correspond à un encadrement de "Pi/2 secondes". En effet les fonctions cosinus et sinus ont le même comportement à la seule
différence qu'elles sont déphasées de "Pi/2" secondes.
Comme on l'a vu tout en haut de cette page sur la figure de droite (le cercle), le sinus se lit sur l'axe des y et le cosinus
sur l'axe des x. Ces deux axes sont perpendiculaires, ils forment un angle de 90°. Ce "90°" représente exactement "Pi/2" radians (on retrouve le déphasage mentionné plus haut), le radian étant l'unité de mesure d'angle
attendue lorsque nous utilisons les fonctions trigonométriques dans le langage des expressions. D'ailleurs en passant, il est mis à notre disposition deux méthodes de conversion pour les angles: "degreesToRadians()" et "radiansToDegrees()", elles sont utiles par moment.
Selon notre application on va plutôt opter pour un cosinus ou plutôt pour un sinus, suivant par exemple s'il
l'on souhaite que la valeur initiale soit nulle ou pas (cos(0)=1 et sin(0)=0).
Remplacer le cosinus par le sinus dans l'expression précédente ferait commencer le "Tracé" non pas en bas ni en haut mais au
milieu de la composition (à l'extrême gauche).
Note
Comme il est souvent plus commode de voir la fréquence comme le nombre d'oscillations en 1 seconde (plutôt que d'avoir à raisonner avec ce "1/(2*Pi)"
et de créer des compositions aux durées "barbares"), on multiplie en général le facteur "time" par "2*Pi".
Ainsi pour une composition de 1s par exemple, en écrivant quelque chose du type:
Math.cos( freq * time * 2 * Math.PI ) ;
nous aurons six oscillations si nous choisissons une fréquence de "6",
neuf oscillations si nous choisissons une fréquence de "9", etc. C'est simplement plus pratique.

Remarque
Nous avons dument développé les aspects de ces fonctions trigonométriques pour bien comprendre
leur fonctionnement (amplitude, fréquence, valeur initiale) afin de pouvoir les contrôler en toute connaissance de cause
lorsque nous les utiliserons un peu plus tard dans des animations de simulations physiques.
|
|