Aide pour After Effect, techniques, expressions.

dimanche 22 mars 2009

look me in 2d

Alors alors, comment faire pour qu'un calque en regarde un autre, ou du moins que sa rotation soit fonction de la position d'un autre.
Tout d'abord, reregardons ça:






















Imaginez que notre objet est sur le point 0, et que l'objet cible soit sur le point "tan", ou du moins sur l'axe de la ligne verte, ça revient au meme.
On cherche donc l'angle A.
Et bien on a cette formule :
tan(A)=coté opposé / coté adjacent.

Par coté adjacent, on parle du coté qui appartient à l'angle, est qui n'est pas la ligne verte (la ligne du cosinus donc, de 0 à 1)
Et par coté opposé, et bien c'est l'autre segment, celui qui n'appartient pas à l'angle (et toujours différent de la ligne verte), la ligne qui va donc de 1 à tan.

Passons à la pratique :

a=position;
b=thisComp.layer("Rouge sombre uni 1").transform.position;

Ca c'est simple, ce sont les deux variables de position. Celle du calque, et celle de la cible.

V=sub(b,a);

Là on crée le vecteur qui correspond à la ligne verte, la ligne qui va de a vers b.

radiansToDegrees ( Math.atan2 ( V[1],V[0] ))

Math.atan2 : il ne s'agit pas de la tangente, mais de la tangente dans le sens inverse.
Quand vous écrivez Math.tan(angle), ça vous donne la tangente de l'angle.
Math.atan2(tan), ça vous donne l'angle de la tangente.
Même chose pour avec Math.acos et Math.asin.
Petite finesse avec atan2, les deux "coté" sont séparés par une virgule.

Donc dans Math.atan2(), on doit inscrire la tangente, c'est donc coté opposé/coté adjacent.
C'est très simple, il suffit de prendre les composantes sur x et y du vecteur.
Reregardez le dessin, surtout la ligne verte. Le coté adjacent et le coté opposé corresponde bien aux composantes x et y de la ligne verte.
On note donc V[0] (sur x) et V[1] (sur y).
Et comme d'habitude, radiansToDegrees, car Math.atan2 donne un angle en radians.

Un petit exemple mixant plein de choses qu'on a vu, j'ai jamais dit que c'était joli.













On verra plus tard le coup de la taille qui change, mais vous avez les outils pour le faire.

10 commentaires:

  1. Salut Saucisse!
    Un détail m'échappe dans ta démonstration.
    Tu dis que Math.atan(), on doit inscrire la tangente, c'est donc coté adjacent/coté opposé.

    or pour moi la tangeante c'est justement l'inverse, à savoir coté opp/coté adjacent.

    Dans ton code tu fais également y/x ou V[1]/V[0], soit la tangeante normale quoi,

    si j'ai bien compris en somme,
    x = Math.tan(y);
    est la meme chose que y = Math.atan(x);

    donc la tangeante est égale à coté opp/coté adj,
    et arc tangeante est égale à coté adj/coté opp?

    Une fois de plus merci pour tes explications et ton blog

    RépondreSupprimer
  2. Je ne sais pas où tu as lu "coté adjacent/coté opposé". J'ai relu mon blabla, oui il s'agit bien de "tan=coté opposé/coté adjacent", donc on a bien V[1]/V[0].
    Et pour l'arctangeante, c'est bien cela.
    Mais en fait, j'ai fait une petite erreur dans mon texte...
    Il fallait écrire ça :
    radiansToDegrees ( Math.atan2 ( V[1]/V[0] ))

    Note le atan2, j'avais donc oublié le 2.
    Il s'agit d'une fonction différente qui donne l'angle en échange de la tangente (V[1]/V[0]).

    Voilà pourquoi ça te semblait bizarre !

    Désolé pour la faute de frappe, le post est corrigé également.
    Merci pour ta remarque en tout cas.

    RépondreSupprimer
  3. ERRATUM:
    Ca y est, j'ai vu où est ce que j'avais écrit "coté adjacent/coté opposé", c'est corrigé!

    merci Chatton.

    RépondreSupprimer
  4. alors juste pour chipoter encore un peu, j'ai essayé tes formules, et tu as ecrit :

    radiansToDegrees(Math.atan2(V[1]/V[0]);

    je comprenais pas pourquoi ca me sortait une erreur, ca me disait qqchose du genre "division par zero, erreur blabla"

    si je ne m'abuse, il faut juste mettre une virgule à la place du / et tout fonctionne!

    Merci pour ta reactivité une fois de plus mon cher saucisse, si tu n'existais pas il faudrait t'inventer!

    Au passage, je crois connaitre ton cousin la power ball power desire! des news récentes de lui?

    RépondreSupprimer
  5. Oui en effet, j'ai corrigé le atan en atan2, et du coup j'ai oublié de corriger la virgule.
    Merci encore une fois pour ton observation.

    Sinon, il faut vraiment que tu m'expliques ta dernière phrase...

    RépondreSupprimer
  6. ahahah :)
    une video vaudra mieux que de longs discours :)

    http://www.youtube.com/watch?v=eDdLrmbgfvU

    j'espere que cette page nostalgie te procurera une émotion intense :)

    RépondreSupprimer
  7. Au passage, je me permets de te demander un petit coup de pouce.

    J'ai bien reproduit l'exemple que tu donnes en fin d'article, à un détail pres : Je n'arrive pas à controller la taille des barres en fonction de la position du rond central.

    Je suis arrivé à le faire, mais c'est pas super flexible..

    En gros, je calcule l'echelle de ma barre en fonction de la longueur du vecteur qui va de la base de la barre (où se situe le point d'ancrage de la barre en gros), jusqu'au rond central.

    J'ai donc utilisé un truc du genre sur l'echelle de mes barres :

    scaleY = linear(longueurVecteur,0,longueurMax,0,100);
    et ensuite fini l'expression avec

    [transform.scale[0],scaleY];

    2 problèmes dans mon raisonnement :
    - longueurMax = longueurVecteur, donc ca déconne (j'ai bidouillé avec une autre variable qui calcule la length entre les memes points, et ca fonctionnait mais bon..)
    - l'echelle qui va de 0 à 100, mais bon ça a ses limites car si je déplace mon rond un peu plus que voulu, bah ma barre ne grandit plus...

    J'ai bien essayé de chercher un rapport qui pourrait bouger entre 0 et 1, voire aller au delàs de 1 pour multiplier le scaleY, mais rien à faire je bloque...

    Aide moi saucisse!!

    (au passage j'ai aussi essayé avec un beam, mais pfff ça marche encore moins :( )

    Merciii!

    RépondreSupprimer
  8. Pour ceux que ca interesse j'ai trouvé une solution :

    admettons V comme le vecteur défini
    j'ai écrit sur la prop scale de ma barre :

    rapport = valeurQueVousVoulez;
    scalerY = length(V)/100*rapport;
    [transform.scale[0],scalerY];

    et le tour est joué

    RépondreSupprimer
  9. Ha bah tu vois, quand on cherche on trouve...
    J'ai d'ailleurs fait un nouveau post à ce sujet, et c'est la même chose! C'est fou non ?

    RépondreSupprimer
  10. Incroyable! tu es mon hero saucisse! :)

    RépondreSupprimer