Forums Développement Multimédia

Aller au contenu

deplacement proportionnel d'un clip, appel aux matheux

CODE Actionscript

25 réponses à ce sujet

#1 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 17 January 2013 - 20:51 PM

salut tous le monde !

Je bosse actuellement sur une classe qui permet le déplacement d'un clip de manière proportionnel.

C'est a dire qu'il reste tout le temps sur l’hypoténuse du triangle formé par la distance entre le clip et le point en x et en y et cela en fonction de sa vitesse

pour une vitesse uniforme je faisais :
deplacement en x = distance en x*vitesse/(distance en x + distance en y)
deplacement en y = distance en y*vitesse/(distance en x + distance en y)

mais la je veux pouvoir avoir deux valeurs différentes pour la vitesse sur l'axe x et sur l'axe y du coup ca serait peut etre plus une formule trigonométrique...je vous montre en image l'idée :

Image IPB

ici pour deux valeurs de vitesse y différente mais une meme valeur de déplacement x on a deux avancées différentes...quelle formule/code conditionnel pourrait résoudre ce schéma?

merci d'avance ;)

#2 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 17 January 2013 - 21:01 PM

Moi, je n'ai jamais dépassé le niveau 3ème… … alors je ferais une simple "pente" :-)

pente = destination.y/destination.x;
// c'est le "rapport" de cette droite. (si ma mémoire est bonne)

A partir de là, tu choisis une vitesse de déplacement pour les x, et la vitesse en y est automatique :
objet.x+=vitesse;
objet.y+=vitesse*pente;

#3 Galacta

    Etudiant Ingénieur

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 689 messages

Posté 17 January 2013 - 21:09 PM

Sinon tu utilises les fonctions affines, ax+b est ta fonction que tu configures avec les paramètres que tu veux, object.y = a*object.x + b, ça ne suffirait pas ?
Word hard, play hard.

#4 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 17 January 2013 - 22:38 PM

je ne vois pas vraiment comment, a vrai dire...il faut prendre en compte que les deux vitesses peuvent être différente (c'est pas juste une qui peut varier) j'ai fait une source pour vous montrer un peu l'idée. Le clip doit rejoindre l'autre en restant sur le trait mais en optimisant son déplacement par rapport à la plus grande vitesse tout en veillant a ce que l'autre valeur ne soit pas dépassée il faut que le déplacement.
Mais quand on y pense même si le déplacement en x est de 15 et le déplacement en y de 1 il se peut que ce soit le 15 qui soit une valeur trop faible et donc qu'on se retrouve avec un deplacement de 15,0.5, tout dépend de l'angle (vous me suivez?)

mis à part si je m'embrouille l'esprit -^

www.packupload.com/9B7N4LQZ7VA

#5 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 17 January 2013 - 22:43 PM

Bonsoir,

Quelques précisions:

Voir le messagedarkrat, le 17 January 2013 - 20:51 PM, dit :

pour une vitesse uniforme je faisais :
deplacement en x = distance en x*vitesse/(distance en x + distance en y)
deplacement en y = distance en y*vitesse/(distance en x + distance en y)
Si tu veux que ton clip se déplace à la vitesse de 5 pixels par image, par exemple, la bonne formule est
longueur = racine carrée de [ (distance en x)² + (distance en y)² ]
deplacement en x = distance en x * vitesse / longueur
deplacement en y = distance en y * vitesse / longueur

Si tu appliques ces déplacements en x et en y à chaque image de ton animation, ton clip se déplacera bien d'une distance de 5 pixels par image.

Voir le messagedarkrat, le 17 January 2013 - 20:51 PM, dit :

mais la je veux pouvoir avoir deux valeurs différentes pour la vitesse sur l'axe x et sur l'axe y
La vitesse sur l'axe des x, c'est la variation du x du clip à chaque image. C'est "deplacement en x" dans la formule précédente.
De même, la vitesse sur l'axe des y, c'est la variation du y du clip à chaque image. C'est "deplacement en y" dans la formule précédente.
Ces deux vitesses ne sont pas égales. Enfin si, elles le sont dans un cas particulier, quand le triangle est isocèle (distance en x = distance en y). Dans tous les autres cas ces vitesses sont différentes.

Voir le messagedarkrat, le 17 January 2013 - 20:51 PM, dit :

ici pour deux valeurs de vitesse y différente mais une meme valeur de déplacement x on a deux avancées différentes...quelle formule/code conditionnel pourrait résoudre ce schéma?
Je ne comprend ni ton dessin ni ta question. Chaque point vert à des x et des y différents sur ton schéma. Si je dessine les points qui ont le même déplacement en x et des déplacements en y j'obtiens ceci:
Image attachée: schema.gif (cliquer pour agrandir)
Un des 2 points n'est pas sur l'hypothénuse. Pour un même deplacement en x il y a un seul déplacement en y qui laisse le point sur l'hypothénuse.

Ou alors pour cause d'incompatibilité de vocabulaire je ne comprends rien à ta question ;) (dldler et galacta n'ont pas eu l'air gênés donc ils ont peut-être compris, eux!)



Ah mais je vois à l'instant ton 2eme message. Je vais aller voir ta source.

#6 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 17 January 2013 - 23:13 PM

En fait, ta question c'est:
Comment déplacer un clip sur l'hypoténuse d'un triangle?
C'est ça?

Dans ce cas Dldler et Galacta te donnent les bons éléments de réponse. Moi aussi d'ailleurs, avec une formule qui fonctionne même si le point de destination est à la verticale du point de départ. Traduit en AS en reprenant ton code ça donne:


import flash.events.MouseEvent;

var vitesse:Number=5;
var distanceX:Number = destination.x-clip.x;
var distanceY:Number = destination.y-clip.y;
var longueur:Number = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
var vitesseX:Number = distanceX / longueur * vitesse;
var vitesseY:Number = distanceY / longueur * vitesse;
function avancer(pevt:MouseEvent){
        clip.x += vitesseX;
        clip.y += vitesseY;
}

stage.addEventListener(MouseEvent.CLICK,avancer);
 

Ceci marchera quelque soit la position de la destination, d'un côté ou de l'autre du point de départ, et aussi à la verticale.


Compléments, puisque je suis en forme:

Le problème avec le code précédent, c'est qu'on n'est pas sûr que le clip va arriver exactement sur le point de destination. Si on donne une vitesse de 10 pixels par pas, et que la longueur de l'hypoténuse est 56, le clip va aller à 10, puis 20, 30, 40, 50, 60 pixels de son point de départ, mais jamais 56.
Cela peut se résoudre en décidant, plutôt qu'une vitesse en pixel par pas, du nombre de pas qu'on veut pour que le clip arrive à destination:

var nombreTotalDePas:Number=5;
var distanceX:Number = destination.x-clip.x;
var distanceY:Number = destination.y-clip.y;
var vitesseX:Number = distanceX / nombreTotalDePas;
var vitesseY:Number = distanceY / nombreTotalDePas;
function avancer(pevt:MouseEvent){
        clip.x += vitesseX;
        clip.y += vitesseY;
}

Qui peut bien sûr s'écrire plus succintement:

var nombreTotalDePas:Number=5;
var vitesseX:Number = (destination.x - clip.x) / nombreTotalDePas;
var vitesseY:Number = (destination.y - clip.y) / nombreTotalDePas;
function avancer(pevt:MouseEvent){
        clip.x += vitesseX;
        clip.y += vitesseY;
}

Il reste un problème, c'est que si nombreTotalDePas est grand, à force de faire des additions de nombres à virgule, le clip arrivera pas tout à fait sur le point de destination. Il faut je pense un grand nombre de pas pour que ça se voit, peut-être que ça ne t'arrivera jamais. Je donne quand même un code qui permet d'éviter ça:

var nombreTotalDePas:Number=5;
var distanceX:Number = destination.x-clip.x;
var distanceY:Number = destination.y-clip.y;
var vitesseX:Number = distanceX / nombreTotalDePas;
var vitesseY:Number = distanceY / nombreTotalDePas;
var nombreDePasFaits:Number=0;
var xDuDébut:Number = clip.x;
var yDuDébut:Number = clip.y;
function avancer(pevt:MouseEvent){
        nombreDePasFaits += 1;
        clip.x = xDuDébut + vitesseX * nombreDePasFaits;
        clip.y = yDuDébut + vitesseY * nombreDePasFaits;
}


#7 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 17 January 2013 - 23:27 PM

Ca me tue un peu de te le dire mais tu écris deux pavés, tu travailles sur ma source... et je pense qu'on s'est toujours pas compris :/

pour le déplacement final j'ai coupé court je fais une simple condition qui teste si l'espace restant est inférieur au déplacement qui serait fait sinon.

mais le problème n'est pas la : tu bases la vitesse sur un nombre de pas ou sur une vitesse référence et c'est bien ce que je ne veux pas en fait^^ je veux pouvoir avoir une vitesse différente pour le déplacement horizontal et le déplacement vertical qui est fixée et non calculée à l'aide des distances.

donc si j'ai une vitesse verticale de 30 et une vitesse horizontale de 2 le clip pourra, uniquement dans son déplacement optimal, se déplacer de 30 pixels en y et seulement 2 en x, mais une de ces deux valeurs sera amoindrie par l'autre dans les autres cas (et pas forcément la plus grande, ca dépend de l'angle) tandis que l'autre sera utilisée dans sa valeur maximale ca veut dire que dans tous mes déplacements j'aurai au moins le 30 en y ou le 2 en x voire les 2 en même temps. La restriction c'est que le clip suive bien le chemin le plus direct entre les deux clips.

#8 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 17 January 2013 - 23:28 PM

J'ai peut-être raté quelque chose mais bon…


A quoi ça sert de vouloir "connaitre" la vitesse réelle. Il me semble qu'on veut juste la simuler ?

Si tu dois rejoindre le point(x,y) en 10 étapes,
- la pente est de y/x
- la vitesse selon l'axe x devra être de x/10
- la vitesse en y sera celle de x multipliée par la pente…

Et si tu veux une vitesse en y au lien de x, c'est la même reflexion mais avec une pente égale à x/y…

Est-ce que c'est une application pratique de quelque chose, que l'on puisse visualiser ou c'est juste un exercice virtuel ?

#9 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 17 January 2013 - 23:38 PM

Voir le messagedarkrat, le 17 January 2013 - 23:27 PM, dit :

je veux pouvoir avoir une vitesse différente pour le déplacement horizontal et le déplacement vertical qui est fixée et non calculée à l'aide des distances.

Si tu as une vitesse différente en x et en y, tu définis une droite. Si tu n'as pas calculé ces valeurs en fonction de ton point de destination, tu as peu de chances que ton clip se rende vers un autre clip par le chemin le plus court… Je pense que c'est ça que l'on ne comprends pas.

Tu as trois valeurs :
- destination
- vitesse x
- vitesse y

Tu ne peux pas avoir 3 valeurs qui viennent de nulle part. 2 valeurs, oui, mais elles t'imposent la troisième.

#10 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 17 January 2013 - 23:42 PM

les trois valeurs sont imposées par l'utilisateur de la classe, le calcul consiste a respecter une des deux vitesse et a adapter l'autre pour rester sur la droite

edit : le problème étant de savoir qu'elle valeur il faut changer, parce que ce n'est pas forcément la plus grande suivant l'angle

#11 Jano 95

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 4558 messages

Posté 17 January 2013 - 23:45 PM

Moi je me pose cette question : Pourquoi chercher des complications mathématiques ou physiques alors qu'il existent les Tweens.

Déplacer un clip sur l'hypoténuse d'un triangle en 4 lignes :

import fl.transitions.Tween;
import fl.transitions.easing.*;
var maTweenX:Tween = new Tween(monClip, "x", Regular.easeIn, monClip.x, monClip.x + 300 , 3, true);
var maTweenY:Tween = new Tween(monClip, "y", Regular.easeIn, monClip.y, monClip.y - 50 , 3, true);
 

Fichier(s) joint(s)



#12 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 17 January 2013 - 23:49 PM

parce que par après je dois être en mesure de tester les collisions et le declenchement d'éventuels scripts sur chaque point de passage du clip

#13 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 17 January 2013 - 23:54 PM

Voir le messagedarkrat, le 17 January 2013 - 23:27 PM, dit :

Ca me tue un peu de te le dire mais tu écris deux pavés, tu travailles sur ma source... et je pense qu'on s'est toujours pas compris :/
Haha effectivement. C'est régulièrement le plus dur, de se comprendre.
Et note que je ne comprends pas encore bien!
Ou alors si je comprends, je suis tout à fait d'accord avec Dldler.

Ah mais je vois ta réponse

Citation

le problème étant de savoir qu'elle valeur il faut changer, parce que ce n'est pas forcément la plus grande suivant l'angle
Nous arrivons au point où on va pouvoir t'aider je pense. Nous sommes d'accord que la vitesse sur un axe dépend de la destination et de la vitesse sur l'autre axe. Si on fournit les deux vitesses comme tu dis il faut faire un choix. Selon quel critère? C'est à toi de nous le dire. Qu'est-ce qu'on doit pouvoir faire avec ta classe?

#14 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 17 January 2013 - 23:57 PM

Oh peuchère, j'ai compris! Tu veux que la ni la vitesse x n la vitesse y fournie ne soit dépassée. J'ai bon??????

#15 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 18 January 2013 - 00:03 AM

Voir le messagelilive, le 17 January 2013 - 23:54 PM, dit :

Nous arrivons au point où on va pouvoir t'aider je pense. Nous sommes d'accord que la vitesse sur un axe dépend de la destination et de la vitesse sur l'autre axe. Si on fournit les deux vitesses comme tu dis il faut faire un choix. Selon quel critère? C'est à toi de nous le dire. Qu'est-ce qu'on doit pouvoir faire avec ta classe?

cette vitesse dépend de la vitesse de l'autre axe mais est quand même fixée à la base.

Le critère c'est de garder une des deux valeurs au maximum pour obtenir le déplacement le plus grand, l'autre valeur est changée pour s'aligner sur la droite (hypothénuse)

Citation

Oh peuchère, j'ai compris! Tu veux que la ni la vitesse x n la vitesse y fournie ne soit dépassée. J'ai bon??????

ah oui, elle ne doivent pas être dépassée la tu me suis ;) ce sont les valeurs maximums du déplacement.

#16 Jano 95

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 4558 messages

Posté 18 January 2013 - 00:04 AM

Voir le messagedarkrat, le 17 January 2013 - 23:49 PM, dit :

parce que par après je dois être en mesure de tester les collisions et le declenchement d'éventuels scripts sur chaque point de passage du clip

var tempo:Timer = new Timer(1);
tempo.addEventListener("timer", control);
tempo.start();
import fl.transitions.Tween;
import fl.transitions.easing.*;
var maTweenX:Tween = new Tween(monClip, "x", Regular.easeIn, monClip.x, monClip.x + 300 , 3, true);
var maTweenY:Tween = new Tween(monClip, "y", Regular.easeIn, monClip.y, monClip.y - 50 , 3, true);
function control(Evt) {
if (monClip.hitTestObject(mur)) {
  txt.text = "BOUM";
};
};
 

Cela répond il à ta question ?

Fichier(s) joint(s)



#17 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 18 January 2013 - 00:04 AM

Alors donc, on a :

vfu_x (vfu pour vitesse fournie par l'utilisateur)
vfu_y (idem)

pour aller d'un point A à un point B, donc :
A_x et A_y
B_x et B_y

Et tu recherches v_x et v_y telle que l'une des vitesses soit une vfu, et que l'autre soit inférieure à la vfu

Bref :

calcule de la pente (ça sera toujours ton rapport entre v_x et v_y)

pente = (B_y - A_y)/ (B_x - A_x);

est-ce que vfu_x*pente est supérieur à vfu_y ?
si oui : il faut prendre v_y = vfu_y; et : v_x = v_y / pente;
sinon : il faut prendre v_x = vfu_x; et : v_y = v_x * pente;

Presque sûr…
[edit : testé, tout semble OK]

#18 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 18 January 2013 - 00:11 AM

Citation

est-ce que vfu_x*pente est supérieur à vfu_y ?
si oui : il faut prendre vfu_y, sinon vfu_x
Comme ils disent aux chiffres et aux lettres: pas mieux!

Et coucou Jano, ça faisait longtemps qu'on s'était pas croisé :)

#19 Jano 95

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 4558 messages

Posté 18 January 2013 - 00:15 AM

Voir le messagelilive, le 18 January 2013 - 00:11 AM, dit :

Et coucou Jano, ça faisait longtemps qu'on s'était pas croisé :)
Je passe régulièrement ( 1 fois par jour environ) mais comme j'en suis resté à la CS3... suis un peu largué et je galère encore avec l'AS3.

Pour ce sujet, je voyais un truc simple avec les Tweens, mais j'ai l'impression que c'est plus compliqué que cela.
Des vitesse imposées...

#20 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 18 January 2013 - 10:55 AM

l'idée semble bonne, quand je la retranscrit j'ai ca

import flash.events.MouseEvent;

var vitesseV:Number=5;
var vitesseH:Number=3;
var pente:Number= (destination.y - clip.y)/ (destination.x - clip.x);
var vitesseVPropor:Number;
var vitesseHPropor:Number;
//est-ce que vfu_x*pente est supérieur à vfu_y ?
if(vitesseH*pente>vitesseV){
    //si oui : il faut prendre v_y = vfu_y; et : v_x = v_y / pente;
    vitesseVPropor=vitesseV;
    vitesseHPropor=vitesseVPropor/pente;
}else{
    //sinon : il faut prendre v_x = vfu_x; et : v_y = v_x * pente
    vitesseHPropor=vitesseH;
    vitesseVPropor=vitesseHPropor*pente;
}


function avancer(pevt:MouseEvent){
    clip.y+=vitesseVPropor;
    clip.x+=vitesseHPropor;
    trace(vitesseVPropor+","+vitesseHPropor);
}

stage.addEventListener(MouseEvent.CLICK,avancer);

la vitesse horizontale se bloque bien tous le temps a 3 et ça suit la ligne :D mais la vitesse verticale fait du freestyle si je place le clip en bas et la destination en haut j'ai une vitesseV de -17 or elle ne devrait pas dépasser les -5

#21 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 18 January 2013 - 11:07 AM

Arf… N'avais point pensé aux coordonnées et vitesses négatives.
Tu as la solution bourrine des Math.abs() croisées avec des conditions sur les signes des deux coordonnées.

Regarde du côté de la comparaison des pentes ?

vf_pente = vfu_y / vfu_x;
ab_pente = (B_y - A_y)/ (B_x - A_x);

if (vf_pente) > ab_pente >>>> sélectionner vf_y et calculer vf_x;
else >>>>> sélectionner vf_x et calculer vf_y;


Non vérifié.
Par contre, ça veut quand même dire que tu as pas mal de cas impossible :

si l'objectif à atteindre est en haut à gauche (cas de base, après tous les autres cas sont des symétries)
- si l'utilisateur donne une vitesse en x négative, ça va être étrange de quand même se déplacer vers la droite…
- si l'utilisateur te donne une vitesse y positive (descendre en Flash), ça va être étrange de quand même se déplacer vers le haut…
- et s'il te donne carrément les 2 négatifs… ???

ça ne me semble pas tout à fait un problème de Math mais de logique. J'ai toujours du mal a imaginer l'usage concret, mais je ne vois pas trop de solution "propre".
En fonction de tes choix pour les 3 points au dessus, tu vas peut-être être amené à faire de bon gros "if" et des choix de vitesse différents.

#22 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 18 January 2013 - 11:25 AM

les valeurs pour les vitesses x et y seront forcément >0 donc pas de soucis de ce coté (enfin ce ne sera pas interdit mais c'est pas prévu pour) les vitesse représentent le déplacement maximum en pixel dans n'importe quelle direction

je regarde a ce que tu me proposes et je te dis si j'arrive à quelque chose ;)

#23 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 18 January 2013 - 11:31 AM

Voir le messagedarkrat, le 18 January 2013 - 11:25 AM, dit :

les vitesse représentent le déplacement maximum en pixel dans n'importe quelle direction

OK. C'est ça qui complique, donc.
Une valeur vitesseX de 5 peut aussi bien donner au final un 5 ou - 5 …
Du coup, ça doit quand même être rattrapable avec des Math.abs() sans devenir trop laid…

#24 dldler

  • Community Manager
  • PipPipPipPipPipPipPipPip
  • 4163 messages

Posté 18 January 2013 - 11:51 AM

Par exemple…


import flash.events.MouseEvent;

var vitesseV:Number = 5;
var vitesseH:Number = 3;
var sens:int = 1;

var destinationX=destination.x - clip.x;
var destinationY=destination.y - clip.y;

if(destinationX<0) vitesseH*=-1
if(destinationY<0) vitesseV*=-1

var pente:Number= destinationY/destinationX;

var vitesseVPropor:Number;
var vitesseHPropor:Number;
//est-ce que vfu_x*pente est supérieur à vfu_y ?
if (Math.abs(vitesseH * pente) > Math.abs(vitesseV))
{
  //si oui : il faut prendre v_y = vfu_y; et : v_x = v_y / pente;
  vitesseVPropor = vitesseV;
  vitesseHPropor = vitesseVPropor * sens / pente;
}
else
{
  //sinon : il faut prendre v_x = vfu_x; et : v_y = v_x * pente
  vitesseHPropor = vitesseH;
  vitesseVPropor = vitesseHPropor * sens * pente;
}


function avancer(pevt:MouseEvent)
{
  fantome.x += vitesseH;
  fantome.y+=vitesseV;

  clip.y+=vitesseVPropor;
  clip.x+=vitesseHPropor;
  trace(vitesseVPropor+","+vitesseHPropor);
}

stage.addEventListener(MouseEvent.CLICK,avancer);
 

Fichier(s) joint(s)



#25 darkrat

    Ceinture Verte

  • Members
  • PipPipPipPip
  • 61 messages

Posté 18 January 2013 - 15:55 PM



victoire !

ca tourne nickel c'est ce que je voulais, je vais étudier ta soluce pour bien saisir l'idée merci beaucoup à vous tous pour votre aide et votre patience !

#26 lilive

  • Moderateur
  • PipPipPipPipPipPipPipPip
  • 2993 messages

Posté 18 January 2013 - 16:25 PM

Haha!!



1 utilisateur(s) li(sen)t ce sujet

0 membre(s), 1 invité(s), 0 utilisateur(s) anonyme(s)