Accélération et décélération

Discussion générale entre passionnés et amateurs de mathématiques sur des sujets mathématiques variés
domledom
Messages: 3
Enregistré le: 29 Juil 2010, 21:33

Accélération et décélération

par domledom » 29 Juil 2010, 21:51

Bonjour

Avec un amis nous nous sommes mis en tête d'écrire un petit programme informatique qui déplace un rectangle à l'écran.

Pour cela nous avons utilisé une méthode simple :
  • Notre rectangle à des coordonnées de départ en x1,y1, une largeur w1 et une hauteur h1
  • Nous lui avons donné des coordonnées d'arrivé en x2,y2,w2 et h2

Pour déplacer notre rectangle, on fait simplement varier un Facteur entre 0 et 1 pour calculer les étapes intermédiaires, Facteur n'étant qu'un pourcentage du déplacement/agrandissement :
  • x = (x2-x1)*Facteur+x1
  • y = (y2-y1)*Facteur+y1
  • w = (w2-w1)*Facteur+w1
  • h = (h2-h1)*Facteur+h1

Jusque là c'est très simple. Là où ça se complique et où franchement cela dépasse mes compétences en mathématique, c'est que nous avons constaté qu'en faisant varier Facteur nous avions un déplacement très linéaire.
Et on s'est donc mis en tête de trouver une solution pour avoir une accélération en douceur puis sur la fin, un décélération en douceur aussi.

Après quelques recherches, la bonne méthode semblerait être Bezier ou Splin degré 3 ou B-Splin ... enfin bref, des choses malheureusement bien trop compliquées pour nous.

Auriez vous une formule (facilement programmable) qui pourrait nous permettre d'atteindre cet objectif ? Avec pourquoi pas une variable qu'on pourrait faire varier pour augmenter ou réduire l'effet de vitesse.

En espérant que mon problème vous motives ...

Merci d'avance



Nightmare
Membre Légendaire
Messages: 13817
Enregistré le: 19 Juil 2005, 18:30

par Nightmare » 30 Juil 2010, 01:22

Salut,

premièrement, je ne comprends pas trop :

Nous lui avons donné des coordonnées d'arrivé en x2,y2,w2 et h2


Durant le déplacement, les dimensions du rectangles varient aussi?

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 30 Juil 2010, 06:39

salut,

les modifications du rectangles varient aussi?

* x = (x2-x1)*Facteur+x1
* y = (y2-y1)*Facteur+y1
* w = (w2-w1)*Facteur+w1
* h = (h2-h1)*Facteur+h1

Apparemment ui!

Sinon, pour piloter la vitesse de déplacement du rectangle.
Supposons sur laxe des x.
Voici un graphe tres simple :
Image
La courbe tracée représente la vitesse de la position x du rectangle en fonction du temps.

Par exemple, au temps t_1, ton rectangle a atteint une vitesse v_1 = v_t(t_1).
Toi cque tu peux faire c'est fixer les vitesses aux différents points arbitrairement. (et si tu veux etre mieux, rajouter des points).
Sur le graphe, on commence avec une vitesse nulle, mais tu te doutes qu'on pourrait lacher le rectangle avec une vitesse initiale!
(donc v_t(0) = v_0 = 10 par exemple au lieu de v_0 = 0).

Tu remarques qu'on termine par une pente douce à la fin (zone verte), et que la vitesse finale est nulle.

Ensuite, comment on s'en sert :
tu echantillones ton axe des x suivant le temps.
Pour tout
t compris entre [0 et t1], tu vas assigner la vitesse v(t) correspondant dans la zone bleue foncée.
Pour déterminer la vitesse associée, spas dur, c'est leq dune droite :

ordonnée a lorigine : v_0
D'ou leq de la droite pour t dans [0;t1] :
Tu fais pareil pour chacune des zones coloriées.

Maintenant pour remonter aux positions (c'est un peu cqui nous intéresse lol) :
Tu te sers du fait que la vitesse c'est la dérivée de la position, cad que
, pour h suffisamment petit.
nous on veut le contraire : x(t) en fonction de v(t)...donc on intègre :

avec a et c des constantes.
Pour la première zone (bleue foncée) :
On à (cque tas définit dans le premier poste)
pour un temps t compris entre 0 et t1, tu as

Ensuite pour la seconde zone, la position de départ c'est donc

et on aura donc
pour t dans [t_1;t2]
etc...

Le problème que tu vois, c'est qu'il faut pouvoir sarreter à x_2. C'est donc à toi définir des vitesses telles que tu dépasses pas x_2.
Pour ca, on peut remarquer que comme la position c'est l'intégrale de la vitesse, ca revient à dire que c'est comprise entre la courbe de la vitesse, l'axe des abscisses et l'ordonnée.
donc typiquement
et que cette somme, ca doit donner x_2 - x_1 (la distance que ton rectangle a parcouru.
Donc cque jte propose, c'est de mettre les différents temps t_1,t_2,...en fonction de t, ex : 0.1t,0.4t,0.8t, bref...
Du coup, tu obtiens alors
Et tu nas plus qu'à résoudre lequation en t!

J'ai pas le temps de me relire, mais jdois etre pas trop loin de la vérité. Enfin, j'espère.
la vie est une fête :)

domledom
Messages: 3
Enregistré le: 29 Juil 2010, 21:33

par domledom » 30 Juil 2010, 14:34

Bonjour

Tout d'abord, merci pour vos réponses.

A Nightmare :

Oui, le rectangle peut prendre n'importe quel taille et position à l'arrivé (par contre, le ratio w/h est toujours constant).

A fatal_error :

Ne serait-il pas plus simple de passer par un calcul de surface ? (En fait, c'était mon idée première.)

Si je reprend la forme de colline que tu as présenté
En calculant la surface à différents instant (exemple : surface de 0 à t1, surface de 0 à t2) et en divisant cette surface obtenue par la surface totale de la colline, est-ce que ça ne pourrait pas marcher ?
  • x = (x2-x1)*Surface(Temps)/SurfaceTotale+x1
  • Plus le sommet de la colline est déplacée vers la gauche plus l'accélération initiale est brutale et la décélération douce.
  • Plus le sommet de la colline est déplacée vers la droite plus l'accélération initiale est douce et la décélération brutale.
  • Plus le sommet est élevé est plus l'amplitude de vitesse est importante.

Et la question subsidiaire si ça peut marcher : Comment calcul t'on la surface de la colline à un instant t (sachant que pour la surface total, t=1)

Merci d'avance

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 30 Juil 2010, 18:02

Boulette de moi, les x(t) ont une forme du style

où c représente l'offset au début de l'intervalle
v_i représente la vitesse au début de l'intervalle
a le coefficient directeur de la courbe sur l'intervalle considéré.



Je développe un peu cque javais ecrit ce matin :
Nommons la premieère zone, la seconde, etc... et la dernière.
Pour la premiere zone, a pour equation :

la vitesse de départ étant nulle, et on commence direct à .
Pour la seconde zone :

On translate l'axe des t pour faire comme si on commencait la zone 1 en
Et de manière générale, si nous avons l'intervalle
pour la zone , alors x aura pour équation

Au final, nous avons donc la position de x à la zone


Donc là déjà, on sait ou est lobjet quelque soit le temps fixé.

Maintenant, on voudrait qu'il sarrete pil en à la fin de la zone cad du certain temps fixé final que jnote .

Ou représente l'aire de la zone k.
Le probleme, c'est que pour l'instant ca "match" pas.
On pose donc un ptit rapport d'homothétie (fin un truc qui agrandit la figure version zoom quoi)

Soit
On agrandit chacune des zones "proportionnellement" par rapport à H.
On note z_k^' nos nouvelles zones, et on va bidouiller tous nos t_i (et v_i) qu'on avait fixé au début.
Nous avons donc pour chacun de nos :

pour faire comme si on commencait à t=0
et pareil pour les
et un rapport de surface de pour la zone considérée. Il suffit des lors de poser et ca devrait rouler :)


En calculant la surface à différents instant (exemple : surface de 0 à t1, surface de 0 à t2) et en divisant cette surface obtenue par la surface totale de la colline, est-ce que ça ne pourrait pas marcher ?

Jpige pas pourquoi tu veux diviser par la surface totale.

Le tout es, comme tu l'as fait remarquer, de calculer l'aire depuis l'axe des ordonnées, jusqu'à l'instant t où on est (cqui représente la distance parcourue).
Tu peux pour cela découper chacune zone en un rectangle + un triangle rectangle dont les aires sont faciles à calculer. Pis après t'additionnes.
Ou alors tutilises cque jtai filé plus haut, ca revient normalement au même.
la vie est une fête :)

Laloi
Messages: 9
Enregistré le: 12 Aoû 2010, 17:10

par Laloi » 12 Aoû 2010, 18:51

Peut-être que j'ai rien pigé, mais si je comprend bien, vous avez un déplacement linéaire simplement parce que vous faites varier "Facteur" de façon linéaire genre :

Code: Tout sélectionner

Facteur =0

while (Facteur  1) {
Facteur = 1
}

}


domledom
Messages: 3
Enregistré le: 29 Juil 2010, 21:33

par domledom » 13 Aoû 2010, 14:33

Bonjour

Merci pour cette réponse.
En fait, oui, le problème vient bien de la variation de facteur qui est totalement linéaire.

En conservant facteur et en reprenant l'idée, voici le programme :

import math

Step = float(1)/10
Total1 = float(0)
Total2 = float(0)

#1ere passe : additionne tous les résultats
Facteur = float(0)
while Facteur<1 :
..Total1 = Total1+math.sin(math.radians(180*Facteur))
..Facteur = Facteur+Step

print "Total1="+str(Total1)

#2eme passe : Recommence en calculant le % atteint
Facteur = float(0)
while Facteur<1 :
..Total2 = Total2+math.sin(math.radians(180*Facteur))
..FacteurAjuste = Total2/Total1
..print "Facteur="+str(Facteur)+" - FacteurAjuste="+str(FacteurAjuste)+\
...." - Delta="+str((math.sin(math.radians(180*Facteur))/Total1)*100)+"%"
..Facteur = Facteur+Step


J'obtiens bien une liste non linéaire :
Total1=6.31375151468
Facteur=0.0 - FacteurAjuste=0.0 - Delta=0.0%
Facteur=0.1 - FacteurAjuste=0.0489434837048 - Delta=4.89434837048%
Facteur=0.2 - FacteurAjuste=0.14203952192 - Delta=9.30960382154%
Facteur=0.3 - FacteurAjuste=0.270175225787 - Delta=12.8135703867%
Facteur=0.4 - FacteurAjuste=0.420807779838 - Delta=15.063255405%
Facteur=0.5 - FacteurAjuste=0.579192220162 - Delta=15.8384440325%
Facteur=0.6 - FacteurAjuste=0.729824774213 - Delta=15.063255405%
Facteur=0.7 - FacteurAjuste=0.85796047808 - Delta=12.8135703867%
Facteur=0.8 - FacteurAjuste=0.951056516295 - Delta=9.30960382154%
Facteur=0.9 - FacteurAjuste=1.0 - Delta=4.89434837048%
Facteur=1.0 - FacteurAjuste=1.0 - Delta=8.97333207441e-15%


Donc ça marche.

Le seul problème c'est que l'écart entre le + rapide et le - rapide est trop faible. En utilisant FacteurAjuste à la place de Facteur pour le calcul des points, le rendu visuel est à peine perceptible.

J'ai essayé en passant math.sin(math.radians(180*Facteur)) au carré, mais ce n'est pas beaucoup mieux.

Il faudrait une courbe plus marquée.

PS: Le programme est en Python. En général je calcul entre 25 et 250 points (de 1 à 10 secondes à 25 images par secondes)

Laloi
Messages: 9
Enregistré le: 12 Aoû 2010, 17:10

par Laloi » 13 Aoû 2010, 15:20

Je ne suis pas sur d'avoir bien pigé la raison pour laquelle tu fais 2 passes...

Tu peux pas juste faire un truc comme ça ? :

Code: Tout sélectionner
import math

Facteur = float(1)/10

Speed = float(1)/10

while Facteur<1 :

...Facteur = min(1, Facteur + Speed * math.sin(math.radians(180*Facteur)))

...print "Facteur="+str(Facteur)



_Désolé s'il y a des erreurs de syntax, j'ai jamais codé en python.

_J'aurais bien adapté Delta pour comparer, mais j'ai pas compris ce qu'il est censé calculer

_Si tu veux ralentir le truc, remplace Speed par un nombre plus petit.

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 13:00

par fatal_error » 14 Aoû 2010, 16:46

salut,

jen profite pour insister sur cque je propose (:D).
Parce que ca marche. (testé en js + canvas FF)

Je reviens pour modifier quelques détails qui étaient pas tres juste, notamment le détail sur l'homothétie.
Il suffit juste de prendre chacun des points et de multiplier leurs coordonnées par h.
Le calcul d'aire est aussi plus agréable (au moins mentalement) que le calcul avec un trinome.
la vie est une fête :)

 

Retourner vers ⚜ Salon Mathématique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 7 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite