Aide pour After Effect, techniques, expressions.

samedi 25 juillet 2009

Molécule

Bonjour bonjour,

de retour parmi vous, nous allons utiliser un peu de trigo pour faire ça :



La question est évidemment de trouver comment bien placer la balle rouge.
Une 1ere solution pourrait biensur être de déplacer le point d'ancrage de la balle rouge, pour que la rotation se fasse autour de la balle jaune.
Toutefois, ça n'est pas terrible, car cela utiliserait la rotation, alors que la position deviendrait inutilisable.

Nous allons donc utiliser la position pour faire tourner la balle rouge autour de la jaune.
Rappelez vous, la trigo nous permet de tranformer une rotation en position.

Créez vos 2 baballes, puis ajoutez deux paramètres glissières à la balle rouge en les nommant "distance" et "angle".

Dans la position de la balle rouge, commençons par :

distance=effect("distance")("Curseur");
angle=degreesToRadians ( effect("angle")("Curseur"));

target=thisComp.layer("Orange uni 1");


target sera donc notre balle jaune.
Je n'explique pas hein. La suite :

P=target.position;

Voilà, P sera le centre de rotation.
Maintenant on cherche la distance entre la boule jaune et la boule rouge.
Cette distance est égale à la moitié du diamètre de la boule jaune + la moitié du diamètre de la boule rouge.

D=(target.width*target.scale[0]/100)/2 + (width*scale[0]/100)/2 +distance;

Ca parait confus, mais les parties rouges font en sorte que le changement d'échelle soit pris en compte.
Le +distance fait donc référence au paramètre glissière, et permet donc à la balle rouge de se décoller de la balle jaune, quand la valeur de distance vaut plus de 0.
La suite :

x=Math.cos (angle)*D;
y=Math.sin(angle)*D;

P+[x,y]

Pour mon animation, j'ai créé une expression wiggle dans l'angle, mais on fait évidemment ce qu'on veut.

Tout ça vous connaissez. A la fin, on rajoute P à x et y pour que P soit tjs le centre.
Dans l'animation, j'ai donc placé un wiggle dans l'échelle de la balle jaune :

x=wiggle(1,100);
[x[0] , x[0] ]

Pourquoi n'ai je pas juste écrit :

wiggle(1,100)

Testez, et vous verrez qu' After Effect vous créera un wiggle différent pour chaque dimension.
Et oui, n'oubliez pas, le wiggle est un mot particulier, qui crée un nombre de variables égale au nombre de valeur présente : 1 pour la rotation, 2 pour l'échelle, 3 pour une position 3d...

Maintenant, utilisons la rotation pour faire roule la balle sur l'autre:








Ouvrez la rotation de la balle rouge :

target=thisComp.layer("Orange uni 2");
angle=effect("angle")("Curseur");

Ca, vous connaissez. La différence avec la position, c'est qu'ici, l'angle est égale à la valeur du paramètre glissière, et non à sa valeur degreesToRadians. En effet, pour la position, on avait besoin de la valeur en radians, car cette dernière était contenu dans un Math.cos et Math.sin.

Plus la balle rouge est petite, plus elle va tourner vite. Il faut donc créer une variable qui définit la différence de périmètre entre la balle jaune et la balle rouge :

p=width*(scale[0]/100)*Math.PI;
P=target.width*(target.scale[0]/100)*Math.PI;
ratio=P/p;

On applique tout simplement la formule "diamètre * pi". Sauf que comme les deux ont *PI, on peut le retirer :
p=width*(scale[0]/100);
P=target.width*(target.scale[0]/100);
ratio=P/p;


Ensuite, il faut savoir que pour qu'une balle fasse un tour autour d une balle d un même diamètre, elle fait 2 tours. Testez, vous verrez.

On a donc pour la dernière ligne :

angle*2*ratio


Et voilà !

3 commentaires:

  1. Salut monsieur Saucisse.
    Merci pour ce Blog passionnant. Je travail sur after depuis quelques années mais mon utilisation des expressions
    était jusqu'à lors plutôt limitée(un wiggle, un loopOut et basta). Grâce à votre travail et à celui d'autres altruistes dans votre genre,
    j'ai largement progressé dans le domaine.
    Cependant, le monde merveilleux des expressions comporte encore pour moi quelques zones d'ombre (et pas des moindres).
    Ce qui m'amène à vous faire part de ma problématique:

    Dans le cadre de ma prod, je doit concevoir un fil de téléphone (ceux en boucles) qui doit être extensible et qui se déforme
    en fonction de l'animation de ses extrémités.

    J'ai d'abord pensé à un bête psd déformé en marionnette mais le résultat est calamiteux (les boucles s'étirent au lieu de se déformer indépendamment.
    j'ai donc entrepris d'appliquer un de vos tutoriaux; le "restons groupés et en ligne, merci" du 5/02/2009.
    Avec ce principe, on a que deux solides à animer (un troisième au milieu serai top), ce qui est tout de même pratique pour nos amis animateurs.
    Dans cette perspective, les solides intermédiaires seraient des compos contenant une boucle dessinée en vecteur.
    Ces dernières seraient "Time remapées" en fonction de leurs écartements. Ainsi, le dessin de chaque boucle changerai en fonction de l'étirement du fil.
    Je pensais à un truc du genre sur le time remap:

    A=this_comp.layer("Boucle_A");
    B=this_comp.layer("Boucle_B");
    point1=A.toComp(A.anchorPoint) ;
    point2=B.toComp(B.anchorPoint);

    delta=sub(point2, point1);
    distance=length(delta);

    t =linear(distance, 181, 916.3, 40, 0) /25;
    if (distance > 1500) t = 1 ;

    à voir.

    Ce sur quoi je bloque, c'est la position de chaque maillons.
    Avec ça sur la position:

    a=thisComp.layer("A").transform.position;
    b=thisComp.layer("B").transform.position;
    plafond=thisComp.layer("plafond").index;
    nombre=thisComp.layer("sol").index-plafond-1;
    Retard=time-3/25;
    R=thisComp.layer("A").transform.position.valueAtTime (Retard);

    V=sub(b,a);
    I=index-plafond;
    increment=linear(I,0,nombre+1,0,1);
    a+V*increment

    Et ça sur l'orientation:

    a=thisComp.layer("A").transform.position;
    b=thisComp.layer("B").transform.position;
    lookAt ( a , b )

    J'obtiens une ligne droite (puisque tous les solides s'alignent sur le vecteur) qui s'étire à loisir.
    Par contre je n'arrive pas à faire en sorte que les solides aient un retard qui permette une déformation du fil en courbes
    (comme dans votre exercice " C'est pas compliqué pourtant..." du 20/03/2009)
    Je sais que tous est dans votre blog pour réaliser mon prop mais j'avoue pédaler dans la semoule depuis deux jours.
    Peut être pourriez vous m'orienter sur ma démarche?
    Sinon tans pis, je continuerai à parcourir le blog avec assiduité.
    Merci de m'avoir lu et désolé pour le commentaire à rallonge (pas trouvé de mail pour vous contacter).
    Bonne continuation.

    Fred

    RépondreSupprimer
  2. Update;
    En mettant ça:
    a=thisComp.layer("A").transform.position.valueAtTime (time-0.04);

    A la place de ça:
    a=thisComp.layer("A").transform.position

    J'obtiens un retard. Mais ce n'est pas trés souple car chaque solide doit avoir une valeur time differente (time-0.04, time-0.05...).
    Breuf, c'est le boxon.
    J'arrête de troller ce beau blog.
    tcho,
    Fred

    RépondreSupprimer
  3. Bonjour Fred,

    sans rentrer dans les détails de ta prose, au sujet du retard :
    Le but est que chaque "maillon" ait son propre retard. Tu veux donc que le retard soit fonction de sa position dans le rang, en partant de la source.
    Il s'agit donc d'utiliser son index "local" comme multiplus du retard.
    Dans ma vidéo "c'est pourtant pas compliqué", la 1ere vidéo attribut un retard aléatoire avec random fixe.
    Pour la 2eme vidéo, le retard est un peu plus compliqué à gérer :
    Les maillons proches des sources ont peu de retard, et plus on s'éloigne de chaque extrémité, plus on est en retard; voilà comment j'ai procédé :
    L'index des maillons varie de 1 à x
    En utilisant un LINEAR, tu peux transformer ce 1->x en 0->PI
    Disons que cette valeur qui va de 0 à PI vaut A.
    Donc tu as B=abs ( sin(A)) qui varie bien de 0 à 1, et tu as bien 0 pour les valeurs en extrémité (1 et x pour les indexes)
    Tu as donc bien ta valeur plafond pour le centre.
    Tu as donc une valeur B qui te sert de variable pour le décalage.
    Voilà j'espère avoir été clair, et j'espère ne pas avoir du de bêtise...

    RépondreSupprimer