Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Les interpolations et fonctions d'easing avec Lazarus VII - Exponentielle et cercle,
Un billet de Gilles Vasseur

Le , par gvasseur58

0PARTAGES

Après les degrés de polynômes et les fonctions trigonométriques, les fonctions exponentielles et celles fondées sur l'équation d'un cercle complèteront l'arsenal de nos outils d'easing.

Si l'on désire encore accentuer l'effet d'inertie comme entrevue avec les fonctions à base de polynômes, rien ne vaut l'exponentielle à base 2.

Prenons le cas de la fonction d'easing de type In. L'idée est d'appliquer à 2 un exposant variant entre 10 fois la fraction d'interpolation effectuée à laquelle on ôte 1 (soit 100%) pour obtenir un nombre négatif. La valeur retournée par l'exposant variera entre -9 et 0 : il faudra simplement faire attention au départ jamais atteint puisque le premier pas (AStep) vaut 1. De son côté, l'exponentielle à base 2, affectée d'un tel exposant, renverra une valeur entre tout près de 0 et 1, ce qui permettra de l'appliquer comme le multiplicateur de AChange.

Par conséquent, la catégorie des fonctions Expo sera implémentée ainsi :

Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  
function TMainForm.EaseInExpo(AStart, AChange, AStep: Single): Single; 
// *** INEXPO *** 
begin 
  Result := ifthen(AStep = 0, AStart, 
    AChange * Power(2, 10 * (AStep / fDuration - 1)) + AStart); 
end; 
  
function TMainForm.EaseOutExpo(AStart, AChange, AStep: Single): Single; 
// *** OUTEXPO *** 
begin 
  Result := ifthen(AStep = fDuration, AChange + AStart, 
    AChange * (- Power(2, -10 * AStep / fDuration) + 1) + AStart); 
end; 
  
function TMainForm.EaseInOutExpo(AStart, AChange, AStep: Single): Single; 
// *** INOUTEXPO *** 
begin 
  if AStep = 0 then 
    Result := AStart 
  else 
  if AStep = fDuration then 
    Result := AChange + AStart 
  else 
  begin 
    AStep := AStep / fDuration * 2; 
    if AStep < 1 then 
      Result := AChange / 2 * Power(2, 10 * (AStep - 1)) + AStart 
    else 
      Result := AChange / 2 * (- Power(2, - 10 * (AStep - 1)) + 2) + AStart; 
  end; 
end; 
  
function TMainForm.EaseOutInExpo(AStart, AChange, AStep: Single): Single; 
// *** OUTINEXPO *** 
begin 
  if AStep < fDuration / 2 then 
    Result := EaseOutExpo(AStart, AChange / 2, AStep * 2) 
  else 
    Result := EaseInExpo(AStart + AChange / 2, AChange / 2, AStep * 2 - fDuration); 
end;

Notez que nous avons de nouveau utilisé la fonction ifthen qui, en fonction d'une première valeur booléenne, renvoie soit le deuxième (si True) soit le troisième paramètre (si False).

Dans le même esprit, nous allons définir des fonctions à base de cercle, c'est-à-dire s'appuyant sur l'équation cartésienne du cercle trigonométrique x² + y² = 1 ou encore y² = 1 - x². Voilà encore une valeur unitaire particulièrement intéressante ! Pour obtenir l'ordonnée y, il suffira de calculer la racine carrée de 1- x² (forcément positive ou nulle dans le cercle trigonométrique de rayon 1).

Les fonctions relatives au cercle de la catégorie Circ auront l'implémentation suivante :

Code delphi : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
function TMainForm.EaseInCirc(AStart, AChange, AStep: Single): Single; 
// *** INCIRC *** 
begin 
  Result := - AChange * (Sqrt(1 - Power(AStep / fDuration, 2)) - 1) + AStart; 
end; 
  
function TMainForm.EaseOutCirc(AStart, AChange, AStep: Single): Single; 
// *** OUTCIRC *** 
begin 
  Result := AChange * Sqrt(1 - Power(AStep / fDuration - 1, 2)) + AStart; 
end; 
  
function TMainForm.EaseInOutCirc(AStart, AChange, AStep: Single): Single; 
// *** INOUTCIRC *** 
begin 
  AStep := AStep / fDuration * 2; 
  if AStep < 1 then 
    Result := - AChange / 2 * (Sqrt(1 - Power(AStep, 2)) - 1) + AStart 
  else 
    Result := AChange / 2 * (Sqrt(1 - Power(AStep - 2, 2)) + 1) + AStart; 
end; 
  
function TMainForm.EaseOutInCirc(AStart, AChange, AStep: Single): Single; 
// *** OUTINCIRC *** 
begin 
  if AStep < fDuration / 2 then 
    Result := EaseOutCirc(AStart, AChange / 2, AStep * 2) 
  else 
    Result := EaseInCirc(AStart + AChange / 2, AChange / 2, AStep * 2 - fDuration); 
end;

Forts de notre expérience, nous nous lancerons lors du prochain épisode dans des fonctions encore plus spectaculaires avec effets d'élastique, de rebond et d'aller-retour. A très bientôt !

Une erreur dans cette actualité ? Signalez-le nous !